Posts tagged class

CakePHP 管理画面を作成する方法

2

CakePHP で管理画面を作成する方法です。
管理画面も CakePHP では簡単に作成することができます。

設定

/app/config/core.php の下記のコメントアウトをはずします。
define('CAKE_ADMIN', 'admin');
これで http://www.example.com/admin/controller/action という URL でアクセスできるようになります。
CAKE_ADMIN の値を変更すれば URL の /admin/ の値が変わります。

コントローラ

管理画面で使用するコントローラに管理画面用のアクションを追加します。
管理画面用のアクション名は admin_index のように admin_ が付きます。
この ‘admin’ の部分も CAKE_ADMIN によって変わります。

ビュー

管理画面用のアクションで表示するデフォルトのビューはアクション名と同じです。admin_index.thtml のように admin_ を付けます。

レイアウト

ユーザサイドの画面レイアウトと管理画面はレイアウトが違うことが多いかと思います。管理画面用のレイアウトを admin.thtml のように views/layouts/ に作成します。

管理画面へのアクセス時の共通処理

管理画面のアクセス時の共通処理として、アクセス制限をしたり、画面レイアウトの変更などがあります。
個別にアクションに追加してもいいのですが漏れなどがあるとまずいのでコントローラの beforeFilter メソッドを使用するといいかと思います。
管理画面で使用するコントローラ全てに共通して処理させるために、 /app/app_controller.php の beforeFilter に処理を追加します。
http://www.example.com/admin/contoller/action にアクセスすると
$this->params['admin'] = 'admin'
がセットされます。管理者用URL かどうかにはこれを使用します。また、’admin’ の値は CAKE_ADMIN で指定した値になります。たとえば CAKE_ADMIN を hoge にすると
$this->params['hoge'] = 'hoge'
になります。

if (defined('CAKE_ADMIN') && !empty($this->params[CAKE_ADMIN])) {
    // 管理者用のレイアウトを指定
    $this->layout = "admin";
    // 管理者用ログインチェックなどを行う
}

OpenPNE 管理画面を別ディレクトリにする

1

OpenPNE の管理画面の URL は

http://www.example.com/?m=admin

という URL になります。
これは SNS の URL

http://www.example.com/?m=pc

などと同じ index.php を使用しています。

このため、管理画面だけ IP アドレス制限をしたいなどという場合に、.htaccess などで制限ができません。

OpenPNE のセットアップマニュアルには 「6-3. 管理画面を別ドメインで運用する (オプション)」という内容で別ドメインで運用する方法が紹介されています。

しかし、レンタルサーバなどでバーチャルドメインなどが使用できない場合に管理画面を別ディレクトリにして .htaccess などでIPアドレス制限や Basic 認証をかけられるようにする方法です。

- OPENPNE_DIR
  ├ bin
  ├ lib
  ├ var
  ├ webapp
  ├ webapp_ext
  ├ webapp_biz
  └ config.php
- public_html
  ├ config.inc.php
  ├ index.php

の public_html 以下のファイルを public_html/admin ディレクトリ以下にコピーする

-public_html
  ├  admin  (管理画面のディレクトリ名)
    ├ config.inc.php
    ├ index.php
   ・
   ・
   ・

コピーした public_html/admin/config.inc.php を書き換える

< ?php
/**
 * @copyright 2005-2007 OpenPNE Project
 * @license   http://www.php.net/license/3_01.txt PHP License 3.01
 */

define('OPENPNE_DIR', realpath('../../'));        // ディレクトリ階層が違うので合わせるために変更する
require_once OPENPNE_DIR . '/config.php';

// 管理画面のベースURL設定
define('OPENPNE_ADMIN_URL', 'http://www.exmaple.com/admin/');

// 無効にするモジュール
$GLOBALS['_OPENPNE_DISABLE_MODULES'] = array('pc', 'ktai');

?>

これで、htt://www.exmple.com/admin/?m=admin でアクセスできるようになります。

注意点は ?m=admin をつけないとアクセスできません。
また、元の http://www.example.com/?m=admin でアクセスできないように

// 無効にするモジュール
$GLOBALS['_OPENPNE_DISABLE_MODULES'] = array('admin', 'setup');

を public_html/config.inc.php に追加してください。

また、前回のエントリで紹介した 「特定ページを SSL で接続する」 で管理画面を SSL で接続する設定をしている場合は

// 管理画面のベースURL設定
define('OPENPNE_ADMIN_URL', 'https://www.exmaple.com/admin/');

のように URL も忘れずに https にしておかないとアクセスできなくなります。

OpenPNE 特定ページを SSL で接続する

3

OpenPNE で個人情報などを送信するようなフォームや管理画面を SSL で接続する方法です。

SSL を使用するように設定を変更する

openpne/config.phpの以下の行を変更
特定ページを SSL で接続するように設定
define('OPENPNE_USE_SSL_PARAM', false);define('OPENPNE_USE_SSL_PARAM', true);に変更
これだけで特定ページが SSL で接続されるようになります。

SSL を使用したいアクションを追加する

デフォルトで SSL 接続されるようになっているページ以外も SSL 接続にしたい場合は

$GLOBALS['_OPENPNE_SSL_REQUIRED'] = array(
'pc' => array(
    'page_o_regist_prof',  'page_o_regist_prof_confirm', 'do_o_regist_prof',
    'page_o_regist_intro', 'page_o_ri', 'page_o_regist_end',
    'page_h_config_prof', 'page_h_config_prof_confirm', 'do_h_config_prof',
    'page_h_config_ktai', 'do_h_config_ktai_send',
),
'ktai' => array(
    'page_o_login', 'do_o_login', 'do_o_easy_login',
    'page_o_login2', 'do_o_update_ktai_address',
    'page_o_regist_pre', 'page_o_regist_input', 'do_o_insert_c_member',
    'page_o_regist_end',
    'page_o_password_query', 'do_o_password_query',
    'page_h_config_prof', 'do_h_config_prof_update_c_member',
    'page_h_config_easy_login', 'do_h_config_easy_login',
    'page_h_config_mail', 'do_h_config_mail_insert_c_ktai_address_pre',
    'page_h_pc_send', 'page_h_pc_send_confirm', 'do_h_pc_send_insert_c_pc_address_pre',
    'page_h_config_password_query', 'do_h_config_password_query_update_password_query',
    'page_h_config_password', 'do_h_config_password_update_password',
));

となっているところに SSL 接続したいアクションを追加していく。
例えば、携帯ではリマインダーは SSL 接続になりますが PC では SSL 接続ではありません。
そこで PC でも SSL にしたい場合は上の pc の配列にリマインダーのアクションの “page_o_password_query” を追加します。
これで http://www.example.com/?m=pc&a=page_o_password_query という URL は自動的に
https://www.example.com/?m=pc&a=page_o_password_query へリダイレクトされます。

注意点は上記の URL からフォームが送信される ?m=pc&a=do_o_password_query というURL も SSL にする必要があります。
これをしないとフォームの画面は SSL でも送信先が SSL ではなくなってしまいます。

PC 用のリマインダーを SSL にする場合は “page_o_password_query” と “do_o_password_query” の2つを追加する必要があるということです。

確認画面が入るフォームなどではフォーム画面表示アクション、確認画面表示アクション、実行アクションと3つ追加する必要があります。

ユーザに SSL を使用するか選択させるアクションの追加

ユーザが SSL を使用するか選択できるリストというのもあります。

$GLOBALS['_OPENPNE_SSL_SELECTABLE'] = array(
'pc' => array(
    'page_h_config', 'do_h_config_1', 'do_h_config_2', 'do_h_config_3',
    'page_o_login', 'page_o_tologin', 'do_o_login',
),
'ktai' => array(
    'page_h_config',
));

このリストに追加するとフォームの右上やリンクの下に SSL 用のリンクが表示されユーザが SSL の使用をするか選択することができます。

CakePHP ファイルアップロードするコンポーネント

2

CakePHP でファイルアップロードを簡単に行うコンポーネントです。
ReverseFolds – CakePHP File Uploads

データベースにファイル名、MIMEタイプ、サイズなどを記録し、ファイルは指定したディレクトリへアップロードするようになっています。

ビューにファイルアップロード用のタグを設置

<input type='file' name='userfile[]'/>
複数配置したいときは

<input type='file' name='userfile[]'/>
<input type='file' name='userfile[]'/>

コントローラに使用するコンポーネントを追加

var $components = array('FileHandler');

アップロード処理

$this->FileHandler->setDebugLevel(1);
$this->FileHandler->setRequired(0);
$this->FileHandler->setHandlerType('db');
$this->FileHandler->setDbModel('FileUpload');
$uploadDir = 'path/to';    // アップロードするディレクトリを指定
if ($this->FileHandler->upload('userfile', $uploadDir)) {
    echo 'アップロード成功';
} else {
    echo 'アップロード失敗';
}

実際の処理などはリンク先からダウンロードしたファイルにコンポーネントの他に、ビュー、コントローラ、モデル、SQL と必要なものは入っているのでソースを見てみるとすぐに分かると思います。

アップロードされるファイルは $uploadDir で指定したディレクトリ内にユニークなディレクトリ名を作成してそのディレクトリ内に元のファイル名で保存してくれます。

その他のメソッド

アップロードできるファイルタイプを限定するメソッド
void setAllowedMime( array $mimeTypes )

ファイルの最大容量を設定するメソッド
void setMaxSize( int $size )
などもあります。

CakePHP Pagination まとめ

2

CakePHP の Pagination に関してまとめてみました。

コントローラでコンポーネント、ヘルパーに Pagination を指定

// 使用コンポーネント名
var $components = array('Pagination');
// 使用ヘルパー名
var $helpers = array('Pagination');

コントローラの一覧表示するアクションでの一覧表示取得方法

$this->Pagination->modelClass = 'Model'; // 使用するモデル
$this->Pagination->sortBy = 'created';	 // デフォルトのソートするフィールド名
$this->Pagination->direction = 'DESC';	 // デフォルトの昇順、降順を指定
$this->Pagination->show = 10;			 // 1ページに表示する件数
$conditions = array(); 					 // 検索条件
list($order,$limit,$page) = $this->Pagination->init($conditions);
$lists = $this->Model->findAll($conditions, $fields, $order, $limit, $page, $recursive);

ビューでのヘルパー使用準備

ビューで Pagination ヘルパーを使用できるようにする
< ?php $pagination->setPaging($paging); ?>

ビューでの総件数と表示している件数の表示

< ?php echo $pagination->result('検索結果:', '/', '?'); ?>件
上記のように指定すると「検索結果:1?10/5253件」と表示されます。

ソートするフィールドを変更するリンクを表示する

< ?php echo $pagination->sortBy('field_name', 'フィールド名', 'ModelName'); ?>
field_name にソートするフィールド名、
フィールド名にリンクに表示する名前、
ModelName にはフィールド名が属するモデル名
を指定します。
モデル名は $this->Pagination->modelClass と同じ場合には省略可能です。

また、sortBy メソッドは
veiws/heplers/pagination.php
function sortBy ($value, $title=NULL, $Model=NULL,$escapeTitle=true,$upText=' ^',$downText=' v')
のように定義されています。見て分かるとおり第5、6引数を指定することにより、ソートしたときのリンクのフィールド名につく「^」「v」の文字を変更することができます。

select タグによってソートを指定したいときは sortBySelect メソッドがあります。
function sortBySelect($sortFields, $t='Sort By: ',$upText=' ^',$downText=' v')

SQL BLOB の容量を計算する方法

1

OpenPNE のカスタマイズをしていて会員毎に画像容量の制限をする必要がでてきました。
quota を使用できれば簡単なのですが、OpenPNE は DB に バイナリデータとして画像を保存しているため使用できません。

そこで SQL で容量を計算する方法を考えました。

LENGTH 関数を使用して
SELECT LENGTH(blobカラム)
とすればバイト数を計算できます。

OpenPNE の場合は c_image というテーブルに画像データが格納されています。
そこで特定の会員の日記に使用した画像の容量を計算するのに下記のようにしてみました。

SELECT SUM(LENGTH(i.bin))
FROM c_image as i
LEFT JOIN c_diary d ON(d.image_filename_1=i.filename OR d.image_filename_2=i.filename OR d.image_filename_3=i.filename)
WHERE d.c_member_id=会員ID

得られる値は byte 数になります。

北海道旅行 その4 スープカレー Massarra (マッサーラ)

0

旭山動物園の帰りに札幌でスープカレーを食べました。
カリー専門店 Massarra (マッサーラ)というお店です。
女性のオーナーがやっているお店で店員さんもすごく感じのいい方でした。

スープカレーは初めて食べたのですがすごくおいしく気に入りました!
ご飯のおかわりは自由なのもうれしいサービスですね。

ご飯の上に卵がのっている「かきたま」とトッピング
スープカレー

店内も落ち着いたカフェのような雰囲気
店内2

壁にはフェルトが貼ってあった
店内

BIALETTI Mukka Express ムッカカプチーノメーカー

1

誕生日プレゼントにカプチーノメーカーをもらいました。
普通のエスプレッソメーカーに一緒にミルクも入れられてエスプレッソとミルクフォームを同時に作る感じです。
作るのに少しコツがいるのでまだたまに失敗しますが、おいしいカプチーノが簡単に作れます。

うちは IH ですが真ん中が IH ではなく熱くなるやつ(なんていうのか分からない。。。)なのでそこで使用しています。

できたカプチーノは下のような感じです。

カプチーノ

本当は2カップ分できるのですが、写真のアマゾンのマグカップは大きいので2カップ分入ってしまいました。

お勧めは楽天で売っているペアのマグカップとコーヒー豆がセットになったセットです。
しかもアマゾンよりも安いですよ!



BIALETTI Mukka Express ムッカカプチーノメーカー(牛柄)2カップ用&ペアマグカップソーサー2客セット&自家焙煎珈琲

CakePHP findAll で INNER JOIN する方法

1

開発中の CakePHP の案件でどうしても INNER JOIN する必要があり、かといって SQL を直接書くのは他のコンポーネントとの兼ね合いでできるだけ避けたい(というより無理)な状況だったので、絶対何か方法があるだろうと思いソースを調べたのでメモしておきます。

/cake/libs/model/model_php5.php の findAll メソッドに

$queryData = array('conditions' => $conditions,
    'fields'    => $fields,
    'joins'     => array(),
    'limit'     => $limit,
    'offset'    => $offset,
    'order'     => $order
);

というのがあり、’joins’ に 空の配列を入れている。
この ‘joins’ の使い方を調べたら、

array(
    "type" => "INNER",
    "alias" => "",
    "table" => INNER JOIN するテーブル,
    "conditions" => INNER JOIN の ONに指定する条件,
);

という配列を入れると INNER JOIN してくれるようです。

ただ、findAll の中で joins に空配列を入れているので、findAll を実行するときのパラメータに joins を指定しても無視されてしまう。
そこで、モデルの beforeFind メソッドを使用することにした。このメソッドは findAll の実行する前に呼ばれるメソッドです。

findAll を実行するモデルに次の beforeFind を定義

function beforeFind(&$queryData) {
    $queryData["joins"][] = array(
        "type" => "INNER",
        "alias" => "",
        "table" => "`model_name`",
        "conditions" => array("model_name.field=model_name2.field2"),
    );
    return true;
}

これで実行された SQL を確認すれば INNER JOIN されれいます。

OpenPNE ユーザID からユーザ情報を取得するグローバル関数

1

OpenPNE をカスタマイズしていてユーザID からユーザのニックネームなど簡単に取得できないかと調べてみると、色々なグローバル関数がありました。

openpne/webapp/lib/db/member.php 内で各種定義されています。

ユーザ情報のよく使う部分のみを取得する

関数名
db_member_c_member4c_member_id_LIGHT($c_member_id)
引数
int $c_member_id ユーザID
戻り値
array ユーザ情報

引数はユーザ IDで、ユーザ情報が連想配列で戻されます。

array(
    'c_member_id' => 'ユーザID',
    'nickname' => 'ニックネーム',
    'image_filename' => '画像ファイル名'
)

ニックネームはそのままテンプレートで表示できます。
画像ファイル名は以前のエントリの「OpenPNE 画像の保存、表示方法」や「OpenPNE 画像を色々なサイズで表示する」を参考に表示させることができます。

ユーザ情報を取得する

関数名
db_member_c_member4c_member_id($c_member_id, $is_secure = false, $with_profile = false, $public_flag = ‘public’)
引数
int $c_member_id ユーザID
bool $is_secure `c_member_secure`の項目を取得するかどうか
bool $with_profile `c_member_profile`の項目を取得するかどうか
string $public_flag プロフィール項目を取得する場合の公開設定(public, friend, private)
戻り値
array ユーザ情報

その他

まだまだ色々な関数があります。興味ある方はソースを調べてみるとよいかと思います。

Go to Top