読者です 読者をやめる 読者になる 読者になる

dari88's diary

これから趣味にするプログラミング/PHP/javascript/kohana/CMS/web design/

kohanaのテスト12-11・・・写真の一覧表示機能を作る

 今日のお題は写真の一覧表示機能です。データベースにバイナリで保存した写真をどうやって見せるのか?って所が面白いです。

 

一覧表示用のビュー

 これはトップページの記事の一覧表示と同じ流れで作れます。サンプルコードは長くなるので、github に置いてあるものを見て下さい。

  ・メインページのビュー
  ・入れ子にする部分のビュー

 

モデル

 ZF のページネターにデータベースのクエリを渡す部分です。

・kohana/application/classes/model/test12/posts.php に追加

    public function selectimage($array) {
        $select = DB::select('ID', 'post_author', 'post_date', 'post_date_gmt', 'extention', 'org_name', 'uq_name', 'tn1_name', 'tn2_name', 'title', 'description')
                ->order_by('ID', 'DESC')
                ->from('wp332_post_images');
        if ($array) {
            $select->where_open();
            foreach ($array as $key => $value) {
                $select->and_where($key, '=', $value);
            }
            $select->where_close();
        }

        return $select->execute();
    }

 カラムを全部セレクトすると一覧表示がもさっと遅くなります。巨大な写真データ部分を除いてセレクトします。

 次は写真データそのものをゲットするモデルです。

・kohana/application/classes/model/test12/posts.php に追加

    public function getimage($id, $c) {
        $select = DB::select('ID', $c)
                ->where('ID', '=', $id)
                ->from('wp332_post_images')
                ->execute();
        return $select->get($c);
    }

 

コントローラー

 先ずはコンテンツの一覧表示部分を生成するコントローラです。

・kohana/application/classes/contents/upload.php

<?php defined('SYSPATH') OR die('No direct access allowed.');

class Contents_Upload {

    static function images($page, $author) {

        $model = Model::factory('test12_posts');
        if ($author) {
            $array = array('post_author' => $author);
        } else {
            $array = NULL;
        }

        $select = $model->selectimage($array);
        $paginator = Zend_Paginator::factory($select);

        if (!$page) {
            $page = 1;
        }

        $paginator->setCurrentPageNumber($page);
        $pagecount = $paginator->count();

        $op = '';
        if ($author) {
            $op = '';
        }
        $hp = 'test12_upload';
        $firstpage = $hp . '?page=1' . $op;
        $beforepage = $hp . '?page=' . ($page - 1) . $op;
        $nextpage = $hp . '?page=' . ($page + 1) . $op;
        $lastpage = $hp . '?page=' . $pagecount . $op;
        if ($page == 1)
            $beforepage = $hp . '?page=1' . $op;
        if ($page == $pagecount)
            $nextpage = $hp . '?page=' . $pagecount . $op;

        $view = View::factory('test12/upload/media');
        $view->data = $paginator;
        $view->single = FALSE;
        $view->firstpage = $firstpage;
        $view->beforepage = $beforepage;
        $view->nextpage = $nextpage;
        $view->lastpage = $lastpage;

        return $view->render();
    }

}

?>

  これは記事の一覧表示の時と殆ど同じです。

 次はビューに書き込んだ写真のリンクに応答するコントローラです。リクエストの引数に応じて出力が変わります。

・kohana/application/classes/controller/test12/mediaview.php

<?php defined('SYSPATH') OR die('No direct access allowed.');

class Controller_Test12_mediaview extends Controller {

    public function action_index() {

        $loginuser = Auth_Wplogin::instance()->get_user();
        if (!$loginuser)
            die();
        $user_ID = Auth_Wplogin::instance()->user_ID($loginuser);
        $id = $_GET['id'];
        $type = $_GET['type'];
        isset($_GET['html']) ? $html = 1 : $html = NULL;

        $model = Model::factory('test12_posts');
        $img = $model->getimage($id, $type . '_img');
        $ext = $model->getimage($id, 'extention');
        $org_name = $model->getimage($id, 'org_name');

        $content_type = array(
            'jpg' => 'image/jpeg',
            'png' => 'image/png',
            'gif' => 'image/gif',
        );

        if ($html) {
            echo "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head>";
            echo "<body><image src='test12_mediaview?id={$id}&type={$type}' /><br />{$org_name}</body></html>";
        } else {
            header('Content-type: ' . $content_type[$ext]);
            print $img;
        }
    }

}

?>

 原画の表示要求とかの場合にはコントローラが直接 HTML を送出しちゃいます。

 最後はメインページのコントローラです。

・kohana/application/classes/controller/test12/upload.php

<?php defined('SYSPATH') OR die('No direct access allowed.');

class Controller_Test12_upload extends Controller {

    public function action_index() {

        $loginuser = Auth_Wplogin::instance()->get_user();
        if (!$loginuser)
            $this->request->redirect('test12');
        isset($_GET['page']) ? $page = $_GET['page'] : $page = NULL;
        isset($_GET['p']) ? $p = $_GET['p'] : $p = NULL;

        $user_ID = Auth_Wplogin::instance()->user_ID($loginuser);

        $view = view::factory('test12/upload/upload');
        $view->head02 = view::factory('test12/postnew/head02');
        $view->adminmenu = view::factory('test12/postnew/adminmenu');
        $view->help = view::factory('test12/postnew/help');
        $view->screen_option = view::factory('test12/postnew/screen_option');
        if($p=='upload'){
            $view->media = view::factory('test12/postnew/uploadify');
            $view->media->folder = $loginuser;
        }else{
            $view->media = Contents_Upload::images($page, $user_ID);
        }
        $view->wpadminbar = view::factory('test12/postnew/wpadminbar');
        $view->wpadminbar->loginuser = $loginuser;

        $this->response->body($view);
    }

}

?>

 

動作試験

 一覧表示の HTML には写真のサムネールに対するリンクが張ってあります。これに対応していちいちデータベースからサムネールを出してやるので、レスポンスはどんなものだろうかと楽しみにしていたのですが、全く問題にならない速さです。

 そもそもファイルシステムとデータベースの違いって何だろうかと考えてみます。ファイルシステムだって一種のデータベースですよね。今現在の構成ですと、どちらも同じハードディスクに入っているわけだし、写真データをファイルシステムに置こうがデータベースに置こうがレスポンスは大差ないと考察できます。

 何でデータベースを選択するのかというと、セキュリティー面と管理の容易さだと思います。

 尚、本日までのテスト12のコードを github にて公開しています。

  https://github.com/dari88/kohana-3.2-sample-code