concrete5 Japan Advent Calendar 1日目を担当します。「外部フォーム」について紹介します。


フォームブロック

concrete5には、標準でフォームブロックが用意されています。フォームブロックを使うと、

  1. 訪問者が名前やメールアドレス、問い合わせ内容などを記入する
  2. 訪問者が送信ボタンを押す
  3. 問い合わせ内容が送信され、管理者にメールが届く

という、よくある問い合わせフォームが作成できます。


外部フォーム

「訪問者からの問い合わせを受ける」といった、シンプルな機能であれば、フォームブロックで十分でしょう。また、そのような場合、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/フォルダに、ビューを置きます。

external_form.png

ビュー

ビューのほうがシンプルなので、ビューから説明します。コードは下記のようになっています。

<?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です。

add_external_form.png


作成したコントローラとビューが正しく設置されていれば、選択できます。
concrete5の設定で、キャッシュを有効にしている場合は、キャッシュをクリアしてください。古いキャッシュが残っていると、正しく表示されないことがあります。

明日はtake566さんです。

記事公開日: 2015年12月01日

2018年8月時点で月間25万PVを超えたため、共有サーバーから移... 詳細はこちら

#

ホームページ作成ソフトconcrete5は多言語に対応しています。... 詳細はこちら

#

concrete5のページ属性機能(カスタムフィールドのようなもの)... 詳細はこちら