2011年4月4日月曜日

4/1覚書

1時間目
replyに画像追加の続き。
ex.複数画像の続き

2時間目も同様

3時間目
☆ヘルパー

no_script_nameをONにすることでフロントコントローラーがURLに出なくなる。

4時間目
ヘルパー続き

5時間目
ヘルパーをbbs2に適用

6時間目
schema実行後に生成されるomディレクトリの子クラスに変更点を記述。
親クラスには記述しない。

来週はreply以外のデータ参照もあるそうな。

現時点ソース。カテゴリ未完成だよー;
写真複数にするときはphotoカラム追加と
/web/images/comment2とか複数必要だよー。

コントロール側

 public function executeIndex()
 {
  print_r(sfConfig::get('sf_support_mail'));


  //commentテーブル全行表示降順
  //昇順 ->addAscendingOrderByColumn(column);
  $c = new Criteria();
  $c->addDescendingOrderByColumn(CommentPeer::CREATED_AT);
  $this->comments = CommentPeer::doSelect($c);


  return sfView::SUCCESS;

 }


 public function executeConfirm()
 {
  $this->name = $this->getRequestParameter("name");
  $this->coment = $this->getRequestParameter("coment");
  $this->categorie = $this->getRequestParameter("categorie");
  $photo1 = $this->getRequest()->getFile('photo1');
  $photo2 = $this->getRequest()->getFile('photo2');


 // sleepさせてrootで/tmpを見る
 //sleep(10);

 //画像の一時ファイル判定
 if($photo1["tmp_name"] != '') {

  //保存する画像名はセッションID生成し付与
  session_regenerate_id();
  //myUtil::getFileExtで拡張子判別。帰り値は._gif._png._jpg
  $tmpname1 = 'photo1_' . session_id() .myUtil::getFileExt( $photo1["tmp_name"] );
  //web/uploads/tmpへ画像を移動する
  $this->getRequest()->moveFile('photo1',sfConfig::get('sf_upload_dir').'/tmp/'.$tmpname1);

  //templateにパスを渡している
  $this->photo1 = $tmpname1;
 }

  //画像の一時ファイル判定
 if($photo2["tmp_name"] != '') {

  //保存する画像名はセッションID生成し付与
  session_regenerate_id();
  //myUtil::getFileExtで拡張子判別。帰り値は._gif._png._jpg
  $tmpname2 = 'photo2_' . session_id() .myUtil::getFileExt( $photo2["tmp_name"] );
  //web/uploads/tmpへ画像を移動する
  $this->getRequest()->moveFile('photo2',sfConfig::get('sf_upload_dir').
'/tmp/'.$tmpname2);

  //templateにパスを渡している
  $this->photo2 = $tmpname2;
 }



  return sfView::SUCCESS;
 }

 public function executeHelp()
 {
  return sfView::SUCCESS;
 }

 public function executeResult()
 {

  //nameとmailを変数にして渡す。
  $name = $this->getRequestParameter("name");
  $coment = $this->getRequestParameter("coment");
  $categorie = $this->getRequestParameter("categorie");


  //insertのmember
  //インスタンス化。空のオブジェクトを生成。
  $comment = new Comment();
  //変数にした名前とメールを入力。idカラムは自動なので不要。
  //カラムにcreated_at、update_atがあればSymfonyが自動で一緒にやってくれる。
  $comment->setNickname("$name");
  $comment->setContent("$coment");
  $comment->setCategorie("$categorie");
  //insert文発行
  $comment->save();

  //画像データを変数にして渡す
  $photo1 = $this->getRequestParameter('photo1');
  $photo2 = $this->getRequestParameter('photo2');

  //画像の存在判定
  if($photo1 != '') {

   ///uploads/tmp/'.$photo1から画像を取得
   $src = sfConfig::get('sf_web_dir').'/uploads/tmp/'.$photo1;
   //最新(投稿と同一)のidを取得(autoincrement稼動時)
   $saveName = $comment->getId().myUtil::getFileExt($src);
   //TEMPから/images/comment/".$saveNameへ保存
   $dst = sfConfig::get('sf_web_dir')."/images/comment/".$saveName;

   rename($src, $dst);
   $comment->setPhoto($saveName);
   $comment->save();

  }

  if($photo2 != '') {

   ///uploads/tmp/'.$photo2から画像を取得
   $src = sfConfig::get('sf_web_dir').'/uploads/tmp/'.$photo2;
   //最新(投稿と同一)のidを取得(autoincrement稼動時)
   $saveName = $comment->getId().myUtil::getFileExt($src);
   //TEMPから/images/comment/".$saveNameへ保存
   $dst = sfConfig::get('sf_web_dir')."/images/comments2/".$saveName;

   rename($src, $dst);
   $comment->setPhoto2($saveName);
   $comment->save();

  }


  return sfView::SUCCESS;
 }
index

<div class="line">
<?php echo form_tag("default/confirm","method=post multipart=true")?>
新規投稿<br>
<?php echo textarea_tag("coment", 
array("rows" => "10", "cols" => "30")) ?>

<br>
ニックネーム<?php echo input_tag("name", array("size => 20"))?>

   
カテゴリ

<?php $categorie = sfConfig::get('sf_categorie')?>
<?php echo select_tag("$categorie", 
options_for_select($categorie,$value));?><br>

画像1<?php echo input_file_tag("photo1") ?><br>
画像2<?php echo input_file_tag("photo2") ?><br>

<?php echo submit_tag("送信する") ?><br>

</form>

</div>

<div class="comment">
 <?php foreach ($comments as $comment):?>
  <?php echo $comment->getNickname();?>の投稿
     投稿日時<?php echo $comment->getCreatedat();?>
     カテゴリ:<?php echo $comment->getCategorie();?><br><br><br>

  <?php echo $comment->getContent();?><br><br>
  <?php if($comment->getPhoto()):?>
  <?php echo image_tag('/images/comment/'
.$comment->getPhoto(),"class=imgmain") ?><br><br>
  <?php endif;?>
  <?php if($comment->getPhoto2()):?>
  <?php echo image_tag('/images/comment/'
.$comment->getPhoto2(),"class=imgmain") ?><br><br>
  <?php endif;?>
  <?php echo link_to("返信", "/reply_add/input", 
array("query_string" => "id=".$comment->getId()))?>
 <br><br>

<?php $replys = $comment->getReplys();?>
  <?php foreach ($replys as $reply):?>
<div class="reply">

  <?php echo $reply->getNickname();?>さんの投稿
   返信日時<?php echo $reply->getCreatedat();?><br><br>
  <?php echo $reply->getContent();?><br><br>
  <?php if($reply->getPhoto()):?>
  <?php echo image_tag('/images/reply/'.$reply->getPhoto(),"class=imgmain") ?><br><br>
  <?php endif;?>
</div>
  <?php endforeach;?>
 <?php endforeach;?>

</div>
input
このコメントに返信します
<div>
 <?php echo $comment->getContent();?><br>
 <?php if($comment->getPhoto()):?><br>
 <img src="/images/comment/<?php echo $comment->getPhoto();?>"><br><br>
 <?php endif;?>
</div>

<div class="line">
</div>
返信フォーム<br>

<?php echo form_tag("/reply_add/confirm", "method=post multipart=true")?>
<?php echo textarea_tag("coment", array("rows" => "10", "cols" => "30")) ?><br>
ニックネーム<?php echo input_tag("name", array("size => 20"))?><br>
<br>
画像1<?php echo input_file_tag("photo") ?><br><br>
<?php echo input_hidden_tag('id', $comment->getId()) ?>
<?php echo submit_tag("確認する") ?>
</form>
confirm
<?php echo form_tag("/reply_add/result", "method=post multipart=true")?>
返信内容<br>
<?php echo $coment;?>
<?php echo input_hidden_tag('coment', $coment) ?>
<br>
ニックネーム<br>
<?php echo $name;?>
<br>
画像<br>
<?php if($photo !=""):?>
<img src="/uploads/tmp/<?php echo $photo?>">
<br><br>
<div class="line"></div>
<?php echo input_hidden_tag('photo', $photo) ?>
<?php endif;?>
<?php echo input_hidden_tag('name', $name) ?>
<?php echo input_hidden_tag('id', $id) ?>
<br>

<?php echo submit_tag("完了") ?>
</form>

2011年3月31日木曜日

3/31覚書

1時間目

reply_add実装続き

2時間目

reply_add実装

idを引き継ぐ処理以外は基本おなじなのだねー。

ていうかそのreplyを表示させるのががが。

3時間目
画像アップロード

[name] => notice01.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpyCW55n
[error] => 0
[size] => 83218

ファイル送信時次のプログラムの処理が終わるまでの間、
サーバーのTEMPディレクトリに一時保管されている。

sleep(20);を加えると20秒間処理を止めるので、
その間にPuTTYからrootで入ってcd /tmpで中身を見ると、
-rw------- 1 apache apache 83218 3月 25 16:25 phpJNeLpc
ってファイルがsleepで設定した時間分だけ確認できる。
処理が終われば消える。

4時間目

画像アップロード処理続き
TEMPディレクトリ作成とパーミッション変更

cd web/uploads
mkdir tmp
chmod -R 777 tmp


画像のアップロード
実際に表示させてみる


5時間目
photoカラム追加
ALTER TABLE comment ADD photo text;
schema.yml、model作成
/web/images/commentディレクトリ作成
chmod 777 commentでパーミッション作成

あと画像表示
できたらpreplyも。
replyカラム+/web/images/replyカラムつけてね。

6時間目

あと画像表示
できたらpreplyも
作業続き

めんどいからここでコード。
action.class.php
<?php

class reply_addActions extends sfActions
{
  public function executeConfirm()
  {
   $this->id = $this->getRequestParameter("id");
 $this->name = $this->getRequestParameter("name");
 $this->coment = $this->getRequestParameter("coment");
 $photo = $this->getRequest()->getFile('photo');

   if($photo["tmp_name"] != '') {

  //保存する画像名はセッションID生成し付与
  session_regenerate_id();
  //myUtil::getFileExtで拡張子判別。帰り値は._gif._png._jpg
  $tmpname = 'photo_' . session_id() .myUtil::getFileExt( $photo["tmp_name"] );
  //web/uploads/tmpへ画像を移動する
  $this->getRequest()->moveFile('photo',sfConfig::get('sf_upload_dir').'/tmp/'.$tmpname);

  //templateにパスを渡している
  $this->photo = $tmpname;
 }

 return sfView::SUCCESS;
  }

  public function executeInput()
  {
   //GETで渡されてくるコメントID
   $id = $this->getRequestParameter("id");
   $this->comment = CommentPeer::retrieveByPK($id);
   $this->photo = $this->getRequestParameter("photo");


 return sfView::SUCCESS;
  }

  public function executeResult()
  {
 //idとnameとmailを変数にして渡す。
 $id = $this->getRequestParameter("id");
 $name = $this->getRequestParameter("name");
 $coment = $this->getRequestParameter("coment");

 //replyのupdate
 //インスタンス化。空のオブジェクトを生成。
 $reply = new Reply();
 //変数にした名前とメールを入力。
 $reply->setCommentid("$id");
 $reply->setNickname("$name");
 $reply->setContent("$coment");
 //insert文発行
 $reply->save();

 $photo = $this->getRequestParameter('photo');

  //画像の存在判定
  if($photo != '') {

   ///uploads/tmp/'.$photoから画像を取得
   $src = sfConfig::get('sf_web_dir').'/uploads/tmp/'.$photo;
   //最新(投稿と同一)のidを取得(autoincrement稼動時)
   $saveName = $reply->getId().myUtil::getFileExt($src);
   //TEMPから/images/comment/".$saveNameへ保存
   $dst = sfConfig::get('sf_web_dir')."/images/reply/".$saveName;

   rename($src, $dst);
   $reply->setPhoto($saveName);
   $reply->save();

  }

   return sfView::SUCCESS;
  }
}

inputSuccess.php
このコメントに返信します
<div>
<?php echo $comment->getContent();?>
  <?php if($comment->getPhoto()):?>
  <img src="/images/comment/<?php echo $comment->getPhoto();?>"><br><br>
  <?php endif;?>
</div>

<div class="line">
</div>
返信フォーム<br>

<form action="/reply_add/confirm" method="post" enctype="multipart/form-data">
<textarea name="coment"></textarea><br>
ニックネーム<input type="text" name="name" size="20">
<br>
<input type="file" name="photo"><br>
<input type="hidden" name="id" value="<?php echo $comment->getId();?>">
<input type="submit" value="確認する">
</form>
confirmSuccess.php
<form action="/reply_add/result" method="post">
返信内容<br>
<?php echo $coment;?>
<input type="hidden" name="coment" value="<?php echo $coment;?>">
<br>
ニックネーム<br>
<?php echo $name;?>
<br>
画像<br>
<?php if($photo !=""):?>
<img src="/uploads/tmp/<?php echo $photo?>">
<br><br>
<div class="line"></div>

<input type="hidden" name="photo" value="<?php echo $photo;?>">
<?php endif;?>
<input type="hidden" name="name" value="<?php echo $name;?>">
<input type="hidden" name="id" value="<?php echo $id;?>">
<br>

<input type="submit" value="確認する">
</form>

resultSuccess.php
完了しました。
<a href="/">トップに戻る</a>

パーミッション解説
自分とグループと他人に対してのアクセス権限。
ファイルへの読み(read) 書き(write) 実行(execute)についての権限を与えること。

できる人だけ。
アップロード3つぐらい送って見る。
複数の条件がどーしても思い浮かばない・・・
$photoをどこで複数化するんだああああ。

おまけ
ntpやってなかったので設定。
教科書のサーバー構築の一番下にあるntp設定やればいいよ。
あとcreated_atの表示で詰まった。
_含むばあいは_取っていいみたい。
例】
投稿日時getCreatedat();?>

2011年3月29日火曜日

3/29覚書

1時間目
DBstudyにcontactテーブルを追加
create table contact (
id int not null auto_increment,
name text,
cotent text,
created_at datetime,
primary key(id)
);
※primary key(id)が最初抜けててエラーググって判明;
あぶねー。

schema作成
symfony propel-build-schema
model作成
symfony propel-build-model

lib/modelに
contact.phpとcontactPeer.phpができているか確認。

2時間目

insert復習

actions.class.php
  //insertのcontact。
  //インスタンス化。空のオブジェクトを生成。
  $contact = new Contact();
  //名前と内容を入力。
  $contact->setName('ゆっきー');
  $contact->setCotent('今日はなんとなくやれるかな');
  //insert文発行
  $contact->save();
indexSuccess.php
<div class="tblData">

<table>
 <tr>
  <th>名前</th>
  <th>内容</th>
 </tr>
 <?php foreach ($contacts as $contact):?>
 <tr>
  <td><?php echo $contact->getName();?></td>
  <td><?php echo $contact->getCotent();?></td>
 </tr>
 <?php endforeach;?>
</table>

</div>

updateは省略。
1行削除も省略。
  //全行削除
  $c = new Critreria;
  $contacts = ContentPeer::doselect($c);
  foreach($contacts as $contact){
   $contact->delete();
  }

☆練習問題
contact_addモジュール作成してinsert、confirm、result作成。

3時間目
☆練習問題
contact_addに下記追加。
性別 男性 女性 ラジオボタン
都道府県 prefで
興味のあること チェックボックス

4時間目

もっかいbbs2バックアップしてつくり直し。
んで掲示板reply_addつける。
indexで新規投稿と投稿一覧、各投稿に返信リンク、
新規投稿→confirmで確認→resultで完了
返信リンクid渡し→入力画面id渡し→confirmで確認id渡し→resultで完了

create table reply (
id int not null auto_increment,
comment_id int,
nickname text,
content text,
created_at datetime,
primary key(id)
);

symfony init-module front reply_add
symfony propel-build-schema
symfony propel-build-model
symfony cc
忘れないようにねー

シンボリックリンク
webでln -s /usr/share/pear/data/symfony/web/sf ./sf

ラストまで。

返信の表示処理は明日。
不完全なのでコードは明日。

2011年3月28日月曜日

3/28覚書

1時間目

☆modelによるCRUD(クラッド)
以下の4つの機能を使う。
◆Create
◆Update
◆Delete
◆Read←昨日からやってるデータの呼び出し

◆Create
action側
  //insertのcomment。
  //インスタンス化。空のオブジェクトを生成。
  $comment = new Comment();
  //名前と内容を入力。
  $comment->setNickname('satou');
  $comment->setContent('今日はいい天気');
  //insert文発行
  $comment->save();

  //insertのmember
  //インスタンス化。空のオブジェクトを生成。
  //$member = new Member();
  //名前とメールを入力。idカラムは自動なので不要。
 //カラムにcreated_at、update_atがあればSymfonyが自動で一緒にやってくれる。
  //$member->setNickname("ooyama");
  //$member->setMailaddress("ooyama@sample.com");
  //insert文発行
  //$member->save();

  //最初に必ずセット select * from member;と同じ。
  $c = new Criteria();

View側commentテーブル

<div class="tblData">
<table>
 <tr>
  <th>名前</th>
  <th>内容</th>
 </tr>
 <?php foreach ($comments as $comment):?>
 <tr>
  <td><?php echo $comment->getNickname();?></td>
  <td><?php echo $comment->getContent();?></td>
 </tr>
 <?php endforeach;?>
</table>

</div>

  //$comment+sで複数にする。commentテーブルのすべてのデータを引き出す。
  $this->comments = CommentPeer::doSelect($c);

2時間目
◆Update
Createとの差異は空のオブジェクト生成をしないことだけ。
$member = MemberPeer::retriveByPK();を使う点のみ。
//Update
  $member = MemberPeer::retrieveByPK(5);
  //名前とメールを入力。
  $member->setNickname("ooyama");
  $member->setMailaddress("ooyama@sample.com");
  //insert文発行
  $member->save();

◆Delete
//Delete
  $member = MemberPeer::retrieveByPk(7);
  //memberがあれば削除。こうしないとエラーになる。
  if($member){
   $member->delete();
  }

☆練習問題
1.bbs2でmember_addモジュール作成
2.input、confirm、resultのaction作成
3.resultでinsert処理

1~2は3/23覚書を参考に~。


3時間目
☆練習問題答え合わせ

public function executeConfirm()
  {
 $this->name = $this->getRequestParameter("name");
 $this->mail = $this->getRequestParameter("mail");
   return sfView::SUCCESS;
  }
  public function executeInput()
  {
   return sfView::SUCCESS;
  }
  public function executeResult()
  {
   //insertのmember
 //インスタンス化。空のオブジェクトを生成。
 $member = new Member();
 
 //nameとmailを変数にして渡す。
 $name = $this->getRequestParameter("name");
 $mail = $this->getRequestParameter("mail");

 //insertのmember
 //インスタンス化。空のオブジェクトを生成。
 $member = new Member();
 //変数にした名前とメールを入力。
 $member->setNickname("$name");
 $member->setMailaddress("$mail");
 //insert文発行
 $member->save();

   return sfView::SUCCESS;
  }

4時間目
1.bbs2でmember_list、member_editモジュール作成。
2.モジュール作成。一覧表に編集ページリンクつけて、idを渡す。
3.余裕のある人はdeleteで削除処理

5時間目

作成続き

6時間目
ううむidのReadがどうしても理解できなかった・・・・・・。member_addはさくっとできたのに(つД`)
自力でできなかった人は/bbs2/apps/front/modules/に移動してから、
mv member_list bk.member_list
mv member_edit bk.member_edit
でバックアップとっても一回やろう。

public function executeConfirm()
  {
   //IDを受け取る
 $this->id = $this->getRequestParameter("id");
 //名前、メールアドレスを受け取る
 $this->name = $this->getRequestParameter("name");
 $this->mail = $this->getRequestParameter("mail");


 return sfView::SUCCESS;
  }
  public function executeInput()
  {

   //IDを受け取る
 $id = $this->getRequestParameter("id");
 $this->member = MemberPeer::retrieveByPK($id);
 //名前、メールアドレスを受け取る(オブジェクトごと受け取るときは無しでよい)
 $this->name = $this->getRequestParameter("name");
 $this->mail = $this->getRequestParameter("mail");

 return sfView::SUCCESS;
  }
  public function executeResult()
  {
   //update-member
 //nameとmailを変数にして渡す。
 $name = $this->getRequestParameter("name");
 $mail = $this->getRequestParameter("mail");

 //IDを指定。
 $id = $this->getRequestParameter("id");
 $member = MemberPeer::retrieveByPK("$id");

 //変数にした名前とメールを入力。ここでIDは要らないよ。
 $member->setNickname("$name");
 $member->setMailaddress("$mail");
 //Update実行
 $member->save();

 return sfView::SUCCESS;
  }
insertSucces.php
<form action="/member_edit/confirm/" method="POST">
名前:<input type="text"name="name" value="<?php echo $member->getNickname();?>"><br>
メールアドレス:<input type="text"name="mail" size="30"
 value="<?php echo $member->getMailaddress();?>">

<br>
<input type="submit" name="send" value="確認">
<input type="hidden" name="id" value="<?php echo $member->getId();?>">
</form>
comfirmSucces.php
<form action="/member_edit/result/" method="POST">
名前:
<?php echo $name;?>
です。
<br>
<input type="hidden" name="name" value="<?php echo $name;?>">
メールアドレス:
<?php echo $mail;?>
です。
<br>
<input type="hidden" name="mail" value="<?php echo $mail;?>">
<input type="hidden" name="id" value="<?php echo $id;?>">
<input type="submit" name="send" value="更新する">
</form>
resultSucces.php
完了しました。


おまけ
commentの検索
View側
<form action="/" method="POST">
名前:<input type="text" name="keyword2">
<input type="submit" name="send" value="送信"></form>

action側
  //シンプルなlike検索機能bycomment
  $d = new Criteria();
  $keyword2 = $this->getRequestParameter("keyword2");
  if($keyword2 !=""){
  $d->add(CommentPeer::NICKNAME, "%".$keyword2."%", Criteria::LIKE);
  }
  //$comment+sで複数にする。commentテーブルのすべてのデータを引き出す。
  $this->comments = CommentPeer::doSelect($d);

2011年3月25日金曜日

3/25覚書

1時間目は遅刻

やること
昨日の復習
1.bbs2をbk.bbs2にリネームしてバックアップ
mv bbs2 bk.bbs2
2.front backend mypage
各アプリケーション作成およびdefaultモジュール作成。
3.backendとmypageで/区切りのURLでアクセス
4.frontアプリケーションのレイアウトを変更。

2時間目

1時間目続き。
30分から復習

3時間目
mypageは出るがbackendが出ない。はて。
/bbs2/web/backend/backend.phpの
../../にiが入ってた_| ̄|○
直った。

ちなみにでらっちが/web/main.cssと/apps/front/templates/layout.phpの
中身メールでくれてるよ。昨日とおとといのおいらの記事にもあるけど。
でらっちのみてね~。

member_addはいいのかなあ・・・・・・。

4時間目
retrieveByPK(1);のKは基本

困ったときのデバッグとシンボリックリンク
http://www.shonanbbs.com/front_dev.php
画面が真っ白のときはここを見ればエラーが書いてある。

で、デバッグバーの画像がまだ引っ張れてないので関連付け
bbs2/webで下記実行
ln -s /usr/share/pear/data/symfony/web/sf ./sf

sf -> /usr/share/pear/data/symfony/web/sf
が出ていればデバッグページでF5で出てくるよ。

backendやmypageなどのほかのページには、各ディレクトリへ移動してから
各_dev.phpの../を2個にしておくよ。

ln -s ../sf sf
上の階層(web)からsfを引っ張ってくるよ。

CSSも同じスタイルでよければ
ln -s ../CSS CSS
でつくよ。

セキュリティ上非常に危険なため、リリース前には必ず_dev.phpは削除する。

5時間目
Criteria(クライテリア)による条件指定
WHEREの代わりに使う。

$c = new Criteria();

$c->add(テーブル名Peer::カラム大文字, 指定する値, 条件)
条件を書かない場合はカラム=値と等しい場合となる。
SQL文だとこうなるけど
select * from member whwre id =1;
Symfonyではこうなる

//最初に必ずセット select * from member;と同じ。
  $c = new Criteria();

  //IDが1のデータ
  //$c->add(MemberPeer::ID, 1);

  //member+sで複数にする。1行分のデータを引き出す。
  $members =MemberPeer::doSelectOne($c);

  //指定したIDのみ1行だけ引き出す。
  $member = MemberPeer::retrieveByPK(2);
  //$memberを表示させる。
  //print $member->getNickname();

  print_r ($members);

ソース出すとこうなる。データは配列で受け取る。
Member Object
(
    [id:protected] => 1
    [nickname:protected] => yamazaki
    [mailaddress:protected] => ****@gmail.com
    [password:protected] => 
    [created_at:protected] => 
    [alreadyInSave:protected] => 
    [alreadyInValidation:protected] => 
    [validationFailures:protected] => Array
        (
        )

    [_new:private] => 
    [_deleted:private] => 
    [modifiedColumns:protected] => Array
        (
        )

)

☆DBから名前のデータを引き出す。

action.class.php
  //最初に必ずセット select * from member;と同じ。
  $c = new Criteria();

  //$member+sで複数にする。テーブルのすべてのデータを引き出す。
  $this->members = MemberPeer::doSelect($c);

indexSuccess.php
{を使うとわかりにくいので、:<?php endforeach;?>で囲う。

<?php foreach ($members as $member):?>
<?php echo $member->getNickname();?><br>
<?php endforeach;?>

☆練習問題
名前とメールアドレスをテーブルに出力+CSSで整形

indexSuccessのソース

<div class="tblData">
<table>
 <tr>
  <th>名前</th>
  <th>メールアドレス</th>
 </tr>
 <?php foreach ($members as $member):?>
 <tr>
  <td><?php echo $member->getNickname();?></td>
  <td><?php echo $member->getMailaddress();?></td>
 </tr>
 <?php endforeach;?>
</table>
</div>

MAINCSS
.tblData table {
border-collapse:collapse;
font-size:93%;
margin:5px 0;
}
.tblData th {
background:none repeat scroll 0 0 #EEEEEE;
color:#333333;
font-weight:bold;
padding:5px;
width:120px;
}
.tblData th, .tblData td {
border:1px solid #ddd;
paddig: 5px 10px;
}


6時間目
☆Criteria(クライテリア)による条件指定

条件
Criteria::EQUAL
Criteria::NOT_EQUAL

//最初に必ずセット select * from member;と同じ。
  $c = new Criteria();

  //IDが1のデータ
  //$c->add(MemberPeer::ID, 1);

  //IDがyamazakiのデータ select * from member where nickname ;
  //$c->add(MemberPeer::NICKNAME, 'yamazaki', Criteria::NOT_EQUAL);

  //like指定
  //$c->add(MemberPeer::NICKNAME, "%yama%", Criteria::LIKE);

  //日付指定検索
  //$c->add(MemberPeer::CREATED_AT, "2011-03-01", Criteria::GREATER_THAN);

  //複数条件
  //$c1 = $c->getNewCriterion(MemberPeer::CREATED_AT, "2011-03-01", Criteria::GREATER_THAN);
  //$c2 = $c->getNewCriterion(MemberPeer::NICKNAME, "ya%", Criteria::LIKE);
  //$c1->addOr($c2);
  //$c->add($c2);

  //$member+sで複数にする。テーブルのすべてのデータを引き出す。
  $this->members = MemberPeer::doSelect($c);

忘れてたUPDATE
日付修正ID指定込み
update member set created_at ='2011-03-25' where id =2;
名前文字化け修正ID指定込み
update member set nickname =('名前') WHERE id =2;


☆練習問題 テーブルの上に検索欄追加。余裕のある人はcommentも呼び出して。
indexSuccess側
<form action="/" method="POST">
名前:<input type="text" name="keyword">
<input type="submit" name="send" value="送信"></form>

action側
  //最初に必ずセット select * from member;と同じ。
  $c = new Criteria();
  //シンプルなlike検索機能
  $keyword = $this->getRequestParameter("keyword");
  if($keyword !=""){
  $c->add(MemberPeer::NICKNAME, "%".$keyword."%", Criteria::LIKE);
  }

  //$member+sで複数にする。テーブルのすべてのデータを引き出す。
  $this->members = MemberPeer::doSelect($c);


commentに何も入れてなかった。サンプルに残そー。

insert into comment (nickname,content,created_at) values ('山崎','腰が痛い','2011-03-25');
insert into comment (nickname,content,created_at) values ('みっくみく','ボカロボカロ','2011-03-25');
insert into comment (nickname,content,created_at) values ('サンレッド','コードナンバー046','2011-03-25');
insert into comment (nickname,content,created_at) values ('ウサコッツ','アニマル怪人','2011-03-25');

2011年3月24日木曜日

3/24覚書

1時間目
腰痛&腹痛のため掃除はお休み。
・EclipceでShift+Ctrl+Fキーで勝手に整形してくれる。超便利。
(でも今までの感覚からするとちょっと見づらいかな;)
・☆練習問題解説編
user_addモジュールにinput、confirm、resultのactionを入れよう。
ページの内容は名前を入力→確認→完了の流れで作ろう。
できたらMENUの下に会員登録ってリンクつけてね。

ファイル自体が壊れたりエラーが多い時はPuTTYで削除かディレクトリごと

2時間目

・☆練習問題解説編続き
・メールアドレスの処理を追加
・bbs2にbackendアプリ追加
symfony init-app backend

frontは記事表示を担当。backendで管理機能を担当。
frontコントローラーのリクエストを受けるのはindex.php。
frontアプリケーションのfrontコントローラーはindex.php。

backendコントローラーのリクエストを受けるのはbackend.php。
backendアプリケーションのbackendコントローラーはbackend.php。

backendにdefaultmodule追加
bbs2で以下実行
symfony init-module backend default

2番目以降のURLは省略不可。
ブラウザでアクセスするときは
http://www.shonanbbs.com/backend.php/default/index
SEO的にまずいので/で簡略化だけど3時間目で。

3時間目

アプリ―コントローラーの関係

見栄えの問題やSEO上の考慮から
http://www.shonanbbs.com/backend/default
でアクセスできるように設定する。

1.cd /home/teacher/bbs2/web
に移動

2.backendディレクトリを作成
mkdir backend

3.backend.php backend_dev.phpをbackendディレクトリへ移動
mv backend.php backend_dev.php ./backend

4.htaccessディレクトリをbackendディレクトリへコピー
cp .htaccess ./backend

5.backendディレクトリへ移動
cd backend

6..htaccessの内容を変更する
vi .htaccess
RewriteBaseとRewriteRuleを以下のように変更

8行目
#RewriteBase /の#をとる
22行目
RewriteRule ^(.*)$ /backend/backend.php [QSA,L]
に変更する。

7.backend.phpを開いて下記に変更
3行目
define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/../..'));
/..を1階層増やすだけ。

8.http://www.shonanbbs.com/backend/defaultでアクセスできることを確認。

☆練習問題
mypageアプリを新規追加してbackendと同じようになってみよう。

4時間目

☆練習問題
mypageアプリを新規追加してbackendと同じようになってみよう。

の答え合わせ。

☆YAML
ヘッダー情報はYAML、ymlファイルで管理。
/bbs2/apps/front/config/view.yml

metas:
title: SHONANBBS
に変更し、
symfony cc(CCはキャッシュクリア)
ymlを変更したら必ずsymfony ccを行い、F5でページ更新。

ここの詳しい話は後日。
5時間目
metasの内容を以下に変更。

description: 課題掲示板です。
keywords: WEBエンジニア養成科,php,Symfony
language: ja

変更したらsymfony ccを行い、F5でページ更新。

■出ないとき
キャッシュをクリアする権限をユーザーでなくrootですると、Symfony ccが正常終了しない。
bbs2で
chown -R ユーザー:ユーザー /cache
でキャッシュの権限をユーザーに変更しなおすか、

chown -R755 ユーザー:ユーザー /cache
+パーミッション変更やてみる。


個別に書きたいときは各metasの項目を削除しlayout.phpで直書きか後日行う部品化を使う。

CSSも stylesheets: [main]
標準のCSS正規パス /home/yamazaki/bbs2/web/css/main.cssに存在する。
書き足したいときはカンマ+スペースで区切る
stylesheets: [main, mypage, ・・・]

javascripts: []もある。今はいじらないけど。

has_layout: on

actionの出力結果をレイアウトしなくていいときはoffにできるよ。

layout: layout
layout.phpを使うという意味。名称変更可能。

☆データベース
SQL を使用せずにデータベースを操作する、O/Rマッピングを使う。

O/R マッピングとは、「オブジェクト」と「リレーショナルデータベース」を
マッピング(対応付け)することです。
O/R マッピングは実装時のデータベース操作にかかわる煩雑な作業を軽減してくれます。

SQLのデータの記述はルールが無いため複雑になりやすい。

O/Rマッピングはルールが決まっているので作業効率が上がる。

とりあえずrootでmysqlログインするよー

ログインしたらcreate database study;でDB作成。
show database;でstudyの存在を確認したら

GRANT ALL ON study.* TO ユーザー名@"localhost" IDENTIFIED BY "パスワード";
flush privileges;

ホスト名は同じサーバーならlocalhost、外部からならIPアドレス。

しかし・・・・・・なぜかflush privileges;ができない
ERROR 1146 (42S02): Table 'mysql.servers' doesn't exist
になってしまう。

回避策
use mysql;

を実行し下記コピペ。

CREATE TABLE `servers` (
`Server_name` char(64) NOT NULL,
`Host` char(64) NOT NULL,
`Db` char(64) NOT NULL,
`Username` char(64) NOT NULL,
`Password` char(64) NOT NULL,
`Port` int(4) DEFAULT NULL,
`Socket` char(64) DEFAULT NULL,
`Wrapper` char(64) NOT NULL,
`Owner` char(64) NOT NULL,
PRIMARY KEY (`Server_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table';

も一回flush privileges;でようやく完了。

6時間目
comment、member、テーブル作成。

create table comment (
id int not null auto_increment,
nickname text,
content text,
created_at datetime,
primary key(id)
);

create table member (
id int not null auto_increment,
nickname text,
mailaddress text,
password text,
created_at datetime,
primary key(id)
);

☆Symfonyでのデータベース接続
/bbs2/config/databases.yml
#をすべて取る。

mysql://root@localhost/dbnameを変更
mysql://ユーザー名:パスワード@localhost/study
エンコード設定とプログラムの記述注意点
YAMLは先頭部分の記述は半角スペース2個をひとつと判断している。
この部分の構成は崩さないように。

all:
  propel:
    class:          sfPropelDatabase
    param:
      dsn:          mysql://ユーザー名:パスワード@localhost/study
      encoding: utf8


/bbs2/config/propel.iniの以下を変更

propel.database.createUrl = mysql://root@localhost/
propel.database.url = mysql://root@localhost/bbs2


propel.database.createUrl = mysql://ユーザー名:パスワード@localhost
propel.database.url = mysql://ユーザー名:パスワード@localhost/study

☆schema.ymlを作成する(DB作成後のみ処理可能)
モデルを作成するための設計書にあたるschema.ymlを作成する。
DBを見に行って接続情報・テーブル情報を引き出し、データファイルを作るための設計書を作成。

一般ユーザーでbbs2から実行。
symfony propel-build-schema

vi /bbs2/config/schema.yml
で中身にcommentテーブルなどが出ている。

次にモデルファイルを作成。
bbs2で実行
symfony propel-build-model

cd lib/modelの中身にcommentPeer.phpとmemberPeer.phpができていればおk。

?? テーブル構造に変化があったらschemaとmodel再生成。
独自追加したい場合はschema.ymlとDB両方とも手書き修正。
自動生成させるとせっかく変えた設定が上書きされてしまう。

7時間目

データ入れます。
set names sjis;
忘れないでねー。

INSERT INTO member (nickname, mailaddress) VALUES
('yamazaki', 's****@gmail.com');
INSERT INTO member (nickname, mailaddress) VALUES
("みっくみく", "mmd@gmail.com");
INSERT INTO member (nickname, mailaddress) VALUES
("サンレッド", "sunred@gmail.com");
INSERT INTO member (nickname, mailaddress) VALUES
("ウサコッツ", "usako@gmail.com");

停電なんでここまで。

2011年3月23日水曜日

3/23覚書

腰痛のため4時間目後半から参加。
詳しくは講習の記録をご参照くだされ。

☆準備でちゃんと聞けなかったところ
actions.class.phpの
public function executeIndex()
indexSuccess.php
太字の箇所は同じ名前にする。

ちょっと言い換えてみる。
actions.class.phpで
public function execute動的処理()
出力処理Success.php
この関係は同じ変数で管理するというイメージがいいのかな。
あと大事なこと。executeの後の項目名は最初大文字で。しないと動かないよ。



☆URLとアクションの関係
Symfonyではモジュール+アクションのページ構成が基本となる。
【例】
member_addモジュールのinputアクションにアクセスするとき。
http://www.shonanbbs.com/member_add/input

あと、Virtualhostの設定間違えてた・・・_| ̄|○ゴメンヨー
<VirtualHost *:80>
    ServerName www.kikin.com
    DocumentRoot /home/kikin/web

    <Directory "/home/kikin/web">
        AllowOverride All
        Options -Includes -ExecCGI
    </Directory>

</VirtualHost>

<VirtualHost *:80>
    ServerName www.shonanbbs.com
    DocumentRoot /home/user(要修正)/bbs2/web

    <Directory "/home/user(要修正)/bbs2/web">
        AllowOverride All
        Options -Includes -ExecCGI
    </Directory>
</VirtualHost

以上を踏まえて練習問題。
☆bbs2にblogモジュールを作って出力。

1.PuTTYから一般ユーザーでbbs2に移動→以下実行
symfony init-module front blog
Eclipceに移動→F5で/bbs2/apps/front/modules/blogができてるよ。

2.そこのaction.class.phpを開いたら、
$this->forward('default', 'module');をコメントアウトか
return sfView::SUCCESS;に置き換えちゃおう。

これの意味の詳しいのは基金訓練WEBで。
基本return sfView::SUCCESS;しか使わないようだけどね。

3./blog/templatesのindexSuccess.phpに何か書いてみよう。

4.http://www.shonanbbs.com/blogにアクセス。


5時間目
CSSのこと。

まあこれもFizzBuzzできてりゃなーんとなくわかると思う。
Symfony+CSS使いはかーなーり、重宝されるそうな。
CSSはテンプレサイトいっぱいあるし、見た目で選べるから楽だよ。

CSSでIDは1ページにひとつだけ。クラスは何個でもOK。
実際に作ってみました。

/bbs2/apps/front/templates/layout.php
ちょっとだけ崩れてるかも。ごめんよう。
<div id="header">
SHONANBBS
</div>

<div id="contentWrappr">
<div id="contentLeft">
<?php echo $sf_data->getRaw('sf_content') ?>
</div>

<div id="contentRight">
MENU
<a href="/member_add/input">会員登録</a>
</div>

<div class="clr"></div>
</div>

<div id="footer">
COPYRIGHT © SHONANBBS
</div>

/* */CSSのコメントアウトだよー。
/bbs2/web/css/main.cssの記述
ちょっと違ってるかもだけどごめん。

/* ヘッダ情報 */
#header {
border-bottom:1px solid #ddd;
margin-bottom:10px;
background-color:#228b22;
}
/* ページ全体のレイアウト */
#contentWrappr {
width:850px;
margin:0 auto;
}
/* 左段落レイアウト */
#contentLeft {
width: 600px;
float: left;
}
/* 右段落レイアウト */
#contentRight {
width: 250px;
float: right;
}
/* フッター情報 */
#footer {
border-bottom: 1px solid #ddd;
margin-bottom:10px;
}
/* フロート処理クリア */
.clr {
clear: both;
}

つかCSS久々過ぎて構文吹っ飛んでたさ・・・。
思い出したら馬鹿さ加減でもうね。・ ゚・。* 。 +゚。・.。* ゚ + 。・゚・(ノД`)

ちょっとメモ。
デバッグ用アドレス*****_dev.php/
【例】front_dev.php/

☆練習問題

user_addモジュールにinput、confirm、resultのactionを入れよう。
ページの内容は名前を入力→確認→完了の流れで作ろう。
できたらMENUの下に会員登録ってリンクつけてね。

ちょwwwレヴェル高杉wwwww
でした。
その前の段階のあることをやってなかったもんで;

同時進行でやるとケアレスミス多発でした。
構文は間違ってないのにページ出ねえぇええええ!

☆どうもPOSTやGETの説明だったみたい。

actionでは
$this->変数 = $this->getRequestParameter("変数");
これだけでPOSTもGETも処理するんだって。

defaultのaction.class.phpに記述。
  public function executeIndex()
  {
 $this->name = $this->getRequestParameter("name");
 $this->address = $this->getRequestParameter("address");
 $this->hobby = $this->getRequestParameter("hobby");
   return sfView::SUCCESS;
  }
で、View側。
HELLO! ENOSHIMA!<br>

私の名前は<?php echo $name;?>です。<br>
住所は<?php echo $address;?>です。<br>
趣味は<?php echo $hobby;?>です。<br>

<hr>

<form action="/" method="POST">
名前:<input type="text" name="name"><br>
住所:<input type="text" name="address"><br>
趣味:<input type="text" name="hobby"><br>
<input type="submit" name="send" value="送信">
</form>

このとき最初は表示されなくて、すごく悩んでいたんでつが・・・気づかなかったんでつよ。
formがfromとか。

なんかね、もう。ばかばかばかばかばかばか。

あとは、別actionのページ作ってください、ってとき。
newsSuccess.phpと書かねばならないところを、
news.Success.phpとか書いてた・・・・・・・・・・・・。


・ ゚・。* 。 +゚。・.。* ゚ + 。・゚・(ノД`)


それからやっとこの意味がわかった。

対応するビューは各モジュールのtemplatesディレクトリに次のような命名ルールで関連付けられています。

アクション名 + ビューの種類.php

わかるとなんでもないことなんだよなああああああああああ。

明日は這ってでも行くんで、腰痛よ、治まってくれ~~~~。


以下超ネタバレ。今後のために自力解決推奨。

1.PuTTY一般ユーザーからbbs2で以下実行
symfony init-module front member_add

2.action.class.phpを下記に変更
  public function executeConfirm()
  {
 $this->name = $this->getRequestParameter("name");
   return sfView::SUCCESS;
  }
  public function executeInput()
  {
   return sfView::SUCCESS;
  }
  public function executeResult()
  {
   $this->name = $this->getRequestParameter("name");
   return sfView::SUCCESS;
  }

3.以下のページ作成
/bbs2/apps/front/modules/member_add/templates/confirmSuccess.php
中身
名前:<?php echo $name;?>です。<br>

<hr>

<form action="/member_add/result/" method="POST">
<input type="hidden" name="name" value="<?php echo $name;?>">
<input type="submit" name="send" value="完了">

</form>

/bbs2/apps/front/modules/member_add/templates/inputSuccess.php
中身
メンバ登録!<br>

<hr>

<form action="/member_add/confirm/" method="POST">
名前:<input type="text" name="name"><br>
<input type="submit" name="send" value="確認">
</form>
/bbs2/apps/front/modules/member_add/templates/resultSuccess.php
中身
完了しました。

4.http://www.shonanbbs.com/member_add/inputでテスト。