【Ethna事始め】#7蔵書管理システムのリスト表示部分

蔵書の追加部分を作ったので、次はリスト表示の部分。
これは、
・app/action/Index.php(アクション)
・app/view/Index.php(ビュー)
・template/ja/index.tpl(テンプレート)
・app/Books_Books.php(O/Rマッパー)
の部分に該当します。

まずは、O/Rマッパーの編集です。
Books_Books.phpをエディタに開くとわかりますが、これはApp_ManagerのBooks_BooksManagerクラスと、App_ObjectのBooks_Booksクラスで構成されていて、リスト表示にはBooks_BooksManagerにメソッドを記述していきます。
先にコードを示すと

public function getList()
{
    $ret = $this->getObjectList('Books', null, array('release_on' => OBJECT_SORT_DESC));
    if (Ethna::isError($ret)) {
        return false;
    }
    return $ret;
}

を、Books_BooksManagerクラス内に記述します。
この$this->getObjectList()は、App_Objectの上位に該当するメソッドで、複数のApp_Objectを取得する際に利用するメソッドです。
第1引数に利用するテーブル名、第2引数に検索条件、第3引数にソート条件、第4引数にオフセット値、第5引数にリミット値を指定します。
ここで僕がよく間違えてしまっていた箇所として、第1引数のテーブル名の指定方法があります。よくテーブル名に『_』を区切り文字として利用した命名方法をすることがあります。例えばテーブル名が『hoge_foo』だった場合、ここに指定するテーブル名は『HogeFoo』のようにします。だけれども、App_Objectでは、『hoge_foo』のようにテーブル名を指定します。似たような機能であっても、微妙な際がありますので注意が必要です。
あと、第2引数や第3引数は少々クセのある指定の仕方をします。ここでは細かいことを書きませんが、基本は配列で、応用としてはAppSearchObjectを利用します。詳しくはEthna公式サイトのクラスリファレンスAppSearchObjectの欄をご覧ください。

次にアクションです。ActionFormは利用しないので、ActionClassのサブクラス、Books_Action_Indexのみを騙取します。
これもソースを先に示すと、

function perform()
{
    $book_list = "";
    $books_Man = $this->backend->getManager('Books');
    $books = $books_Man->getList();
    list($num, $list) = $books;

    foreach ($list as $book) {
        $book_list[] = array(
                               'id' => $book->get('id'),
                               'isbn' => $book->get('isbn'),
                               'name' => $book->get('name'),
                               'author' => $book->get('author'),
                               'manufacturer' => $book->get('manufacturer'),
                               'release_on' => $book->get('release_on'),
                               );
    }
    $this->af->setApp('books', $book_list);

    return 'index';
}

です。
4行目の

$this->backend->getManager('Books');

で、BooksテーブルのApp_Managerを取得し、5行目にて先ほど記述したgetList()メソッドを呼び出しています。
getListメソッドで取得した値は配列となっていて、それをlist()で分けています。
$numには取得した値の数(countにあたる内容)が入っていて、$listにはApp_Objectの配列が入っています。そして、$listをforeachで回し、$books_listにApp_Objectを用いて値を入れていきます。
#$books_listに値を入れる処理は、もっと簡潔に書く方法がありそうですが・・・。
18行目で、$books_listをActionFormを利用してテンプレートに値をアサインしています。
アクションの処理は以上です。

最後にテンプレートの記述です。bodyタグ内に以下のような記述をしてください。

{if $app.books != ""}
<table>
  <tr>
    <th>ISBN</th>
    <th>書名</th>
    <th>著者名</th>
    <th>出版社</th>
    <th>発行日</th>
    <th></th>
    <th></th>
  </tr>
{foreach from=$app.books item=book}
  <tr>
    <td>{$book.isbn}</td>
    <td>{$book.name}</td>
    <td>{$book.author}</td>
    <td>{$book.manufacturer}</td>
    <td>{$book.release_on}</td>
    <td><a href="{url action="edit" id=$book.id}">Edit</a></td>
    <td><a href="{url action="delete" id=$book.id}">Delete</a></td>
  </tr>
{/foreach}
</table>
{/if}

<a href="{url action="add"}">New</a>

ここで使っているEthnaの技術は2つ。
先ほどアクションのActionFormを利用してアサインした値を、$app.hogeのようにして取得している点。
そして、Ethnaの組み込みSmarty関数としてのurlです。urlでは、引数としてactionを必須としていて、指定したactionへのURLを自動作成します。また、それ以外のクエリもソースのように指定する事ができます。

これらを記述したら、URLにアクセスしてみてください。

みたいな感じで表示されたらOKです。

削除機能とか、編集機能は考えて作ってみてください。( ゚Д゚)マンドクセーなってきたので、蔵書管理システムはこれで終了。一応、ソースをココに置いておきます。ただし、途中で疲れたのでかなりテキトーです。あと、俺はUTF化したEthnaを使っていたりしますので、動作がなぁ・・・(^▽^;)

追記
・・・作っていて思ったけど、これだと詳細表示部分いらないんだよなぁ。
それと、途中で飽きるなよ、と(苦笑)ま、そのうちリベンジします。

Tags:

【Ethna事始め】#7蔵書管理システムの追加処理Part3

では、DBに登録する処理をperformメソッドに記述していきます。

ここでApp_Objectを利用します。App_Objectを利用する事で、SQLを書かなくてもDBへの追加・編集・削除ができたりします。
実際にperformメソッドに以下のように記述します。

function perform()
{
    $books = $this->backend->getObject('books');
    $books->importForm();
    $books->add();

    header('Location:'.$this->config->get('url'));
?>

まず、

$this->backend->getObject('books');

とすることで、booksテーブルのO/Rマッパーを利用できるようになります。

$books->importForm();

をすると、ActionFormで取得する値をクエリにそのままセットすることができます。元々は

$books->set('isbn', $this->af->get('isbn');
$books->set('name', $this->af->get('name');
...

って感じで、クエリにセットしていくんですが、それらを個別でやるのが面倒なので作ったメソッドだそうです。
んで、

$books->add();

で、実際にDBへのINSERTをおこないます。

まだリスト出力の部分を作っていませんが、これで蔵書の追加処理は完了です。ターミナルなどからmysqlを直接確認すれば、追加されていることがわかると思います。
なお、ISBNの重複に関しては、mysql側でユニークキーを設定しているので、そっち側に一任。本当なら、スクリプト側でやる方が正しいのでしょうが・・・(^▽^;)

では、次にリスト出力の部分を作っていこうと思います。

Tags:

【Ethna事始め】#7蔵書管理システムの追加処理Part2

次に、validateの設定をします。

doneアクションをエディタで開きます。
先ほどはActionFormクラスを書き換えましたが、次はActionClassクラス(Books_Action_AddDoneクラス)を書き換えます。

Books_Action_AddDoneクラスには、prepareperformの2つのメソッド(これら2つの他にauthenticateってクラスも継承されていますが、ここでは触りません)が入っています。prepareメソッドでvalidateとかをして、performメソッドで実際の処理をおこなうとでも思っていたらいいです。

今はvalidateを行うので、prepareメソッドの編集です。

function prepare()
{
    if ($this->af->validate() > 0) {
        return 'add';
    }
    return null;
}

みたいな感じに書き換えてください。

$this->af->validate()

をすると、先ほど記述したActionFormの定義($formの値)にのっとってvalidateを行います。もし定義に合致しないデータであった場合、値が1以上になるためにif内に入ります。if内では(定義に合致)しない場合は、perfomの処理をおこなわず、returnで指定したビュー(この場合はaddビュー)に処理を引き渡します。

エラーの表示はテンプレートに

{if count($errors)}
<ul>
{foreach from=$errors item=error}
<li>{$error}</li>
{/foreach}
<ul>
{/if}

と記述すると、

って感じで表示させることができます。
・・・ものすごくわかりにくい説明だorz

次は、DBに登録する処理をperformに記述していきます。

Tags:

【Ethna事始め】#7蔵書管理システムの追加処理Part1

では、これからは実際にコーディングに入っていきます。

まずは、蔵書の追加処理から行います。Index(リスト表示)から入らないのは、・・・いろいろと理由があったりします。
#リスト表示させるには、App_Manager使わなきゃいけなくて、それはそこそこにややこしいので。だったら、わかりやすい追加処理から書こうかな、と。

蔵書の追加処理に使うファイルは
・app/action/Add.php(addアクション)
・app/action/Add/Done.php(doneアクション)
・app/view/Add.php(addビュー)
・template/ja/add.tpl(addテンプレート)
の4つです。
大雑把な説明をすると、addアクションからdoneアクションにデータが受け渡されます。その受け渡されるデータの定義はdoneアクションがして、フォームはビューとテンプレートがdoneアクションに定義された形で出力します。・・・かえってややこしくなってしまいましたorz

実際に書いていった方が早いので、ちゃっちゃとやっていきます。
まずは、doneアクションをエディタで開きます(addアクションを変更することはありません)。
そのファイルをザッと眺めてください。2つのクラスから成り立ってるのがわかりますでしょうか。
先に書かれているが、Books_Form_AddDoneクラスです。こいつは、ActionFormと呼ばれるクラスのサブクラスで、GET/POSTなどのクエリを管理するクラスです。
後ろの方に書かれているのが、Books_Action_AddDoneクラスです。こいつは、ActionClassと呼ばれるクラスのサブクラスで、実際の処理を記述していくクラスです。
今は、Books_Form_AddDoneクラスを記述していきます。

このBooks_Form_AddDoneクラスの中に

var $form = array();

ってのがあります。ここに受け取るクエリの条件などを記述していきます。
今回、追加処理で受け取るクエリとしまして
・isbn
・name
・author
・manufacturer
・release_on
です。
んで、それぞれの条件を踏まえながら、書いていきますと

var $form = array(
    'isbn' => array(
        'name' => 'ISBN',
        'type' => VAR_TYPE_STRING,
        'form_type' => FORM_TYPE_TEXT,
        'required' => true,
    ),
    'name' => array(
        'name' => '書名',
        'type' => VAR_TYPE_STRING,
        'form_type' => FORM_TYPE_TEXT,
        'required' => true,
    ),
    'author' => array(
        'name' => '筆者名',
        'type' => VAR_TYPE_STRING,
        'form_type' => FORM_TYPE_TEXT,
        'required' => false,
    ),
    'manufacturer' => array(
        'name' => '出版社',
        'type' => VAR_TYPE_STRING,
        'form_type' => FORM_TYPE_TEXT,
        'required' => false,
    ),
    'release_on' => array(
        'name' => '発行日',
        'type' => VAR_TYPE_DATETIME,
        'form_type' => FORM_TYPE_TEXT,
        'required' => false,
    ),
),

って感じです。

次に、ビューを少し書き換えます。
Books_View_Addクラス内に、

var $helper_action_form => array( 'add_done' => null);

ってのを付け加えます。これは、doneアクションで定義したフォーム値をaddビューで使いますよ、って宣言だと思ってもらえば、あながち間違っていないはず。・・・ただ、書かなくても動くのは動くんだよなぁ(^▽^;)

ビューが書けたなら、テンプレートの編集に移ります。
テンプレートのbodyタグ内に

{form ethna_action="add_done"}
{form_name name="isbn"}{form_input name="isbn"}
{form_name name=”name”}{form_input name=”name”}
{form_name name=”author”}{form_input name=”author”}
{form_name name=”manufacturer”}{form_input name=”manufacturer”}
{form_name name=”release_on”}{form_input name=”release_on”}
{form_submit value=”追加する”}
{/form}

って感じで書いてやります。
そこまでできたら、シンボリックリンクをはったURLにaction_add=trueっていうGETクエリをつけたURIにアクセスしてください。(僕の場合だと、http://localhost/~siukaido/books/?action_add=true)
こんなフォームの見れてるでしょうか?

フォームが見れていたら成功。これがActionFormのフォーム出力機能です。

・・・ちょっと長くなってきたので、ここで一回区切ります。

Tags:

【Ethna事始め】#6蔵書管理システムのアクション等の追加

では、今回のシステムに必要なアクションやビューを追加していきます。

まずは簡単な設計を考えます。ミニマムな物を作って、それを拡張していくようにしましょう。
必要な機能としては、
・蔵書のリスト表示
・蔵書の詳細表示
・蔵書の追加フォームと追加処理
・蔵書の編集フォームと編集処理
・蔵書の削除処理
といったところでしょうか。

リスト表示はIndexを使うとして、詳細表示をitem、追加フォームをadd、追加処理をadd/done、編集フォームをedit、編集処理をedit/done、削除処理をdeleteとします。
このうち、ビューが必要なのは、
・蔵書のリスト表示
・蔵書の詳細表示
・蔵書の追加フォーム
・蔵書の編集フォーム
というところでしょう。

では、ethnaコマンドでそれらを追加していきます。
アクションを追加するには、

$ ethna add-action [action name]

ビューを追加するには、

$ ethna add-view [view name]

テンプレートを追加するには、

$ ethna add-template [template name]

ビューとテンプレートを同時に追加するには、

$ ethna add-view -t [view&template name]

としてやります。
#アクション・ビュー・テンプレートを同時に追加するコマンドはないのでしょうかね?あったら便利だとは思うのですが、見つけきれませんでした(^▽^;)
アクション・ビュー・テンプレート名の区切り文字として『_』がデフォルト設定されています。なので、『_』を使うアクション名とかは避けた方が賢明です。あと、頭文字が数字でも上手く行きませんので注意してください。

では、実際に追加していきます。なお、レスポンスは書きませんのでご了承あれ。

$ ethna add-action item
$ ethna add-action add
$ ethna add-action add_done
$ ethna add-action edit
$ ethna add-action edit_done
$ ethna add-action delete
$ ethna add-view -t item
$ ethna add-view -t add
$ ethna add-view -t edit

次にO/Rマッパーを追加しましょう。Ethnaでは、これをApp_ObjectApp_Managerって呼ばれてます。これを使うと、簡単な処理であればSQLを直接記述することなくDB操作を行う事が可能となります。
#あと、キャッシュ処理もしてくれてるので、少しはDBアクセスが減ります。・・・たぶん(^▽^;)

O/Rマッパーを追加するには、

$ ethna add-app-object [table name]

ってしてやります。これで、App_ObjectとApp_Managerが生成されます。

今回であれば、使うテーブルはbooksなので、

$ ethna add-app-object books

としてやります。

これで必要なファイルの生成は完了です。次からは、これらのファイルに、必要な処理を記述していきます。

Tags:

【Ethna事始め】#5蔵書管理システムの初期設定

プロジェクトを作成したので、まずはBooksプロジェクトの初期設定をします。これをしとかないと、O/Rマッパーを使えなかったり、いろいろと面倒なことになります。

プロジェクトのルートフォルダ内のetcフォルダに、books-ini.phpってファイルがあるので、こいつをエディタで開いてやります。

まず、9行目あたりに

'url' => '',

ってのがあるので、そこにエントリポイントのあるURLを書いてやります。

- 'url' => '',
+ 'url' => 'http://localhost/~siukaido/books/',

次に、29行目あたりに、dsnの設定を追加してやります。これはPEAR::DBと同じような書き方ですし、24行目にサンプルがあるんで、それを真似て書いてやります。

+ 'dsn' => 'mysql://root:********@localhost/ethna_recipe',

#僕がよくやる間違いとして、『,』じゃなく、『:』って書いちゃうことがあります。あくまでも配列の値なんですよね(^▽^;)

とりあえずは、これで初期設定はこれだけ。あと、共有で利用するような設定項目(後々使う事になりますが、AmazonWebServiceのIDとか)を追加してやることもできます。ここで設定しておけば、プログラム中に

$this->config->get('hoge');

って感じで呼び出せるので、結構便利だったりします。
#本当なら、defineとかで定数化すべきなのかもしれませんが・・・。

次はアクションやらビューやらを追加していく作業です。

Tags:

【Ethna事始め】#4蔵書管理システムのプロジェクト作成etc

では、ethnaコマンドを使ってプロジェクトを作成していきます。
今は、作業用フォルダにいる状態です。そこで

$ pwd
/Users/siukaido/ethna
$ ethna add-project books

と入力してやると、『ディレクトリを作ってもいいか?』と聞いてくるので、yを入力してやります。すると、必要なフォルダ構成が自動生成されます。まるでRoRのように!!
#倒置法で書くと英語のテキストを和訳してるみたいだなwww

んで、lsでチェックしてやると実際にbooksフォルダが作成されてるので、そこに移動。以降、ここをプロジェクトのルートフォルダとして作業していくことになります。

$ ls -F
books/
$ cd books

このルートフォルダには以下のようなフォルダが作成されてると思います。

$ ls -F
app/     lib/          schema/      tmp/
bin/      locale/     skel/           www/
etc/      log/         template/

このうちのwwwフォルダがエントリポイントが含まれた公開フォルダとなるので、公開フォルダ(嗚呼ややこしい…)にシンボリックリンクでも貼付けてやります。

$ pwd
/Users/siukaido/ethna/books
$ ln -s ~/ethna/books/www/ ~/Sites/books

これで、ブラウザからhttp://localhost/~siukaido/books/にアクセスすることで、booksプロジェクトにアクセスできるはずです。
アクセスできたなら

な感じで表示されてると思います。
これで、第一歩は終了。次からはエディタを用いてガシガシとコーディングです。

※ここまででつまずいたなら、GREE Lab.にもっと詳細に説明がされているので、そちらも参照してください。

Tags:

【Ethna事始め】#3蔵書管理システムの下準備

まずは下準備として、データ項目あたりを云々とします。

書籍データとして、次の項目を扱えるようにします。
・ISBN
・書名
・著者名
・出版社
・発行日
んで、これらを英語表記して
・isbn
・name
・author
・manufacturer
・release_on
としておきます。

EthnaにはRoRみたいに、自動でデータベース設定を行う機能がないので、まずはそこからやりましょう。
#そのうち、Ethnaにも自動でデータベースを設定する機能を付けて欲しいなぁ・・・。

データベース名はethna_recipeで、テーブル名はbooks、項目は上に記した通りです。ユーザは面倒なのでrootでやります(爆)

$ mysql -u root -p
Enter Password:
Welcom(略

mysql> CREATE database ethna_recipe;
Query OK, 1 row affected (0.08 sec)

mysql> USE ethna_recipe;
Database changed

mysql> CREATE TABLE books (
        -> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
        -> isbn VARCHAR( 255 ) NOT NULL ,
        -> name VARCHAR( 255 ) NOT NULL ,
        -> author VARCHAR( 255 ) NOT NULL ,
        -> manufacturer VARCHAR( 255 ) NOT NULL ,
        -> release_on DATE NOT NULL ,
        -> UNIQUE (isbn)
        -> ) ENGINE = MYISAM ;

これでデータベースの設定は終了。ethna事始めとか言っときながら、いっさいethnaに触れてないしwww
次からは実際にethnaコマンドを使ったりしていきます。・・・たぶん。

Tags:

【Ethna事始め】#2Ethnaの下準備

ようやくEthnaの下準備です。とは言っても、インストールされてることを前提に書いているので、一般的な下準備じゃないんですけどねwww

まずは作業用フォルダを作ります。

$ pwd
/Users/siukaido
$ mkdir ethna
$ cd ethna
$ pwd
/Users/siukaido/ethna

って感じで、作業用フォルダを作成して、そこに移動してください。僕はホームフォルダ直下に『ethna』ってフォルダを作っていて、そこにethnaで作成するシステムを突っ込んでいます。
#同様にRoRの作業用フォルダは、ホーム直下のrailsって名前だったりします。安直と言われようが、わかりやすいんだもんwww

・・・うん、下準備って言ってもこれだけwww
次からは、実際のシステムを作る行程です。最初のサンプルは、ライド・オン・Railsにのっとって『蔵書管理システム』ってヤツです。

Tags:

【Ethna事始め】#1 Httpd.conf for Mac

Ethnaの下準備の前に、Apacheの下準備をしておきます。
MacOSXはデフォでApacheがインストールされているので、『システム環境設定』→『共有』を選択してやり『パーソナルWeb共有』にチェックを入れてやればWebサーバが動いてくれます。
#ここらへんは知っているという前提なので、PHPやMySQLの動かし方のような細かいところは書きません。

こんな簡単にWebサーバを起動することができるMacOSXなのですが、デフォで入ってるApacheでは公開フォルダ(~/Sites/)にシンボリックリンクを貼ったとしても、403になってしまいアクセスできません。なので、httpd.confを少しだけいじる必要があります。
#/Liverary/WebServer/Documents/にシンボリックリンクを貼るのであれば、問題はないんですけどね。

ちなみに、Macのhttpd.confは少し奇妙な位置にありまして、/private/etc/httpd内にあったりするので注意が必要です。こういう時、Linuxで育った人間には違和感があったりなかったりwww

$ cd /private/etc/httpd
$ ls -F
httpd.conf
users/
$ cd users
$ ls
siukaido.conf

このsiukaido.confが、ユーザ用公開フォルダに対するコンフィグなので、こいつを少し書き換えます。

- Options Indexes MultiViews
+ Options Indexes FollowSymLinks MultiViews

って感じ。
#このとき、スーパーユーザで処理する必要ありますからね。

細かいところはApacheの仕様書なりを読んでください。僕もよくわかってません(爆)
デフォだと上手く動かなくて、僕自身、かなりハマってしまった箇所なので紹介しときましたwww

Tags:,

次のページ »