concrete5 Japan Advent Calendar 1日目を担当します。「外部フォーム」について紹介します。
フォームブロック
concrete5には、標準でフォームブロックが用意されています。フォームブロックを使うと、
- 訪問者が名前やメールアドレス、問い合わせ内容などを記入する
- 訪問者が送信ボタンを押す
- 問い合わせ内容が送信され、管理者にメールが届く
という、よくある問い合わせフォームが作成できます。
外部フォーム
「訪問者からの問い合わせを受ける」といった、シンプルな機能であれば、フォームブロックで十分でしょう。また、そのような場合、GUIで項目を変更できるフォームブロックが便利です。
しかし、フォームブロックでは用意されていない処理を行いたい場合もあります。そのような場合に、外部フォームが役立ちます。
外部フォームの簡単な例
簡単な例として、「再送信希望する」外部フォームを作ってみます。
名古屋セミナーポータルでは、投稿した内容をメルマガで配信しています。投稿者は一回だけ再送信が希望できるようになっています。再送信を申請するボタンを外部フォームで作っています。
管理者にメッセージを送る、という目的だけ考えれば、標準のフォームブロックでも実現可能です。しかし、「再送信希望する」の場合は、「どのユーザーが」「どの投稿を」再送信申請したのか、が重要な情報です。
この「どのユーザーが」「どの投稿を」という情報をユーザーが手作業で入力するのは手間がかかります。なので、外部フォームとして作成し、をプログラム側でチェックして処理できるようにしています。
作成するファイル
concrete5では、自分で作成したプログラムはapplicationフォルダに置くルールになっています。もし、concreteフォルダ以下に置いた場合、動作はしますが、バージョンアップの時に差分を確認して反映する、という作業が必要になります。なのでapplicationフォルダに置くことが推奨されています。
外部フォームは、ブロックですので、自作プログラムはapplication/blocks/external_formフォルダに置きます。(concrete5本体の外部フォームブロックはconcrete/blocks/external_formです。最初のapplicationとconcreteが異なり、それ以降の階層は同じになるように配置します。)
application/blocks/external_form/form/controllerフォルダに、コントローラーを置きます。
application/blocks/external_form/form/フォルダに、ビューを置きます。
ビュー
ビューのほうがシンプルなので、ビューから説明します。コードは下記のようになっています。
<?php $form = Loader::helper('form'); defined('C5_EXECUTE') or die("Access Denied."); // 現在のページ情報を取得 $c = Page::getCurrentPage(); $status = $c->getAttribute('resend_status'); $pid = $c->cID; if (isset($response)) { ?> <div class="panel callout radius"><?php echo $response?></div> <?php } ?> <?php if (empty($status)) : // 属性 resend_status が空の場合。再配信が希望できる ?> <form method="post" action="<?php echo $view->action('request_resend')?>">
<div class="form-group"> <div style="display: none" > <?php echo $form->text('id_field', $pid)?> </div> </div>
<div class="form-group"> <input type="submit" name="submit" value="メルマガ再送信を希望する" class="button"> </div>
</form> <?php else : // 属性 resend_status が空でない場合。再配信希望は不可 ?> <p>この投稿は、メルマガでの再掲載を依頼済みです(同一内容の再掲載は1回のみです)。 3回以上の配信を希望される場合は、不定期ビジネスニュースの広告として掲載が可能です(有料)。 <a href="/index.php?cID=894">こちら</a>をご覧頂き、検討いただければ幸いです。</p> <?php endif ;?>
通常のフォーム作成とほぼ同じです。concrete5特有なのは、formタグのaction属性に、action('request_resend')?>を設定する、ぐらいです。
コントローラ
コントローラでは、管理者に通知を送る処理を記述しています。
- どのページから送信されたか、をフォームのid_fieldで判定
- 送信者の情報をコントローラで取得
といった処理を行い、自動化しています。
namespace Application\Block\ExternalForm\Form\Controller; use Concrete\Core\Controller\AbstractController; use Page; use User; use UserInfo; use Core;
class RequestResend extends AbstractController {
public function action_request_resend($bID = false) // ビューの $view->action('request_resend') に対応 { if ($this->bID != $bID) { \Log::addEntry('RequestResend: ブロックid取得失敗'); $this->set('response', '正しい操作では無いようです。お手数ですが、ブラウザのキャッシュをクリアしてから、もう一度お試しください。' ); return true; }
// POSTデータを変数に格納する $val = $this->post();
$c = Page::getByID(intval($val['id_field'])); if (!is_object($c)) { \Log::addEntry('RequestResend: ページid取得失敗'); $this->set('response', 'ページ取得ができませんでした。お手数ですが、ブラウザのキャッシュをクリアしてから、もう一度お試しください。' ); return true; } $status = $c->getAttribute('resend_status');
if (empty($status)) { // 属性resend_status に日付を入れる。resend_status に値があれば、再送信申請済み $date = date('Y年m月d日'); $c->setAttribute('resend_status', $date);
// 再送信の申請を、管理者にメールで通知する $mh = Core::make('helper/mail');; $adminUser = UserInfo::getByID(USER_SUPER_ID); $mh->from($adminUser->getUserEmail(), '名古屋セミナーポータル管理者');
//送信したユーザーの情報 $u = new User(); $ui = UserInfo::getByID($u->uID); $yourname = $ui->getAttribute('yourname');
$mh->to($adminUser->getUserEmail()); $mh->setSubject('名古屋セミナーポータル 再投稿申請'); $mailbody = 'タイトル: ' . $c->getCollectionName() . PHP_EOL . PHP_EOL; $mailbody .= '送信者: ' . $yourname . PHP_EOL; $mh->setBody($mailbody); $mh->sendMail(); $response_message = '送信希望を出しました。'; } else { $response_message = 'すでに送信希望済みです。'; }
$this->set('response', $response_message ); return true; }
}
外部フォームを使うには
ブロック「外部フォーム」を使うには、通常のブロック同様、編集画面でブロックを追加すればOKです。
作成したコントローラとビューが正しく設置されていれば、選択できます。
concrete5の設定で、キャッシュを有効にしている場合は、キャッシュをクリアしてください。古いキャッシュが残っていると、正しく表示されないことがあります。
明日はtake566さんです。
記事公開日: 2015年12月01日