Advanced Custom FieldsはWordpressの定番プラグインですが、acf_form()関数によって手軽にフロントページでの投稿/編集を行うことが出来ます。
ユーザー参加型のサイトで、wp-adminダッシュボードを使用させたくない場合などにナイスですね。
Customise WordPress with powerful, professional and intuitive fields
目次
基本
基本形の例
<?php acf_form_head(); ?> <?php get_header(); ?> <main> <?php while ( have_posts() ) : the_post(); ?> <?php acf_form(); ?> <?php endwhile; ?> </main> <?php get_sidebar(); ?> <?php get_footer(); ?>
acf_form_head() を最初に読み込みます。
acf_form()でフォームを表示します。
記事の更新
<?php acf_form_head(); ?> <?php get_header(); ?> <main> <?php while ( have_posts() ) : the_post(); ?> <?php acf_form(array( 'post_id' => 123, 'post_title' => false, 'submit_value' => 'Update the post!' )); ?> <?php endwhile; ?> </main> <?php get_sidebar(); ?> <?php get_footer(); ?>
新規投稿
<?php acf_form_head(); ?> <?php get_header(); ?> <main> <?php while ( have_posts() ) : the_post(); ?> <?php acf_form(array( 'post_id' => 'new_post', 'new_post' => array( 'post_type' => 'event', 'post_status' => 'publish' ), 'submit_value' => 'Create a new event' )); ?> <?php endwhile; ?> </main> <?php get_sidebar(); ?> <?php get_footer(); ?>
固定ページから制御してみる
post上での更新ではなく、いわゆるマイページとなる固定ページから記事の投稿・更新を管理してみます。
下記のページテンプレートを作成します。
- 自分の記事一覧(page-my_posts.php)
- 記事投稿編集(page-edit_my_post.php)
自分の記事一覧(page-my_posts.php)
ログインユーザーの記事一覧を取得し、参照します。
記事編集のページへGETなどでページIDを渡せるようにします。
<?php
/*
Template Name: マイページ/記事一覧ページ
*/
?>
<?php
get_header();
//ログインしていないか、投稿者でなければTOPへリダイレクト
if (! is_user_logged_in() || ! in_array('author', $this_user->roles)) {
wp_redirect( home_url().'/' );
}
$current_user = wp_get_current_user();//ログインユーザー情報を取得
$user_id = $current_user->ID;//ユーザーIDを取得
$query = new WP_Query(
array(
'author' => $user_id,
'posts_per_page' =>10,
)
);
if ( $query->have_posts() ):
while ( $query->have_posts() ):
$query->the_post();
?>
<main>
<h2><?php the_title();?></h2>
<form action="<?php echo home_url(); ?>/edit_my_post/" method="get"><!--記事投稿編集URLを指定-->
<input type="hidden" value="<?php echo $id;//ページIDを渡す ?>" name="editpostID" class="editpost">
<button type="submit">編集する</button>
</form>
</main>
<? endwhile; endif;?>
<?php get_footer();?>
記事投稿編集(page-edit_my_post.php)
<?php
/*
Template Name: マイページ/記事投稿編集ページ
*/
?>
<?php acf_form_head(); ?>
<?php
//対象になるpost_idを取得 (新規の場合は0で)
$editpostID = $_GET['editpostID'];
if($editpostID==''){
$post_id = 0;
}else {
$post_id = $editpostID;
}
$this_user = wp_get_current_user();
if (! empty($_REQUEST['pid'])) {
$post_id = intval($_REQUEST['pid']);
}
//ログインしていないか、投稿者でなければTOPへリダイレクト
if (! is_user_logged_in() || ! in_array('author', $this_user->roles)) {
wp_redirect( home_url().'/' );
}
//本人の投稿ではない場合はマイページへリダイレクト
if (! check_post_id_by_user($post_id)) {
wp_redirect( home_url().'/my_posts/' );
}
acf_form_head();
get_header();
?>
<main>
<?php
if (have_posts()) : while (have_posts()) : the_post();
$opt = array(
'return' => home_url()..'/my_posts/',
);
if (intval($post_id) > 0) {
$opt['post_id'] = intval($post_id);
$opt['post_title'] = true;
$opt['post_content'] = true;
$opt['submit_value'] = '更新';
} else {
$opt['post_id'] = 'new_post';
$opt['post_title'] = true;
$opt['post_content'] = true;
$opt['submit_value'] = '新規登録';
}
acf_form($opt);
the_content();
endwhile; endif;
?>
</main>
<?php get_footer();?>

フロントでの投稿画面
記事の削除/非公開で登録
acf/save_postフックを使用する
・wp_delete_post()で当該の記事を削除
・wp_update_post()で当該の記事ステータスを更新
【functions.php】
// acfで投稿を削除または非公開にする
add_filter('acf/save_post', 'delete_private_post');
function delete_private_post($post_id) {
if (is_admin() || get_post_type($post_id) == '適用しないカスタム投稿タイプ名') {
return $post_id;
}
//削除
if (get_field('delete_this_post', $post_id)) {//「delete_this_post」フィールド(真/偽)で判定
$force_delete = false;// 完全に削除する場合はtrueに設定
wp_delete_post($post_id, $force_delete);
wp_redirect(home_url().'/my_posts/');// 記事が無くなるのでリダイレクトさせる
exit;
}
//非公開
elseif (get_field('private_this_post', $post_id)) {//「private_this_post」フィールド(真/偽)で判定
$args = array(
'ID' => $post_id,
'post_status' => 'private'
);
wp_update_post($args);
return $post_id;
}else {
$args = array(
'ID' => $post_id,
'post_status' => 'publish'
);
wp_update_post($args);
return $post_id;
}
}
上記の場合、カスタムフィールドフィールドタイプ「真/偽」で作成しておき、チェックを入れて更新した場合は記事を削除・更新するようにします。
実際の運用では条件判定を使用して他のフィールドと二段階認証にするなどの対応が望ましいでしょう。

カスタムフィールドで記事のステータスを制御&削除
入力と出力の制限
セキュリティ担保のために入出力の制限を行います。
入力
文字数制限やアップロードファイルの容量制限を行います。
Advanced Custom Fieldsでは管理画面より手軽に設定が行なえます。
出力
XSSなどの対策のためエスケープ処理を行います。
<?php
$str = get_field('フィールド名');
echo esc_html( $str );
?>
引用元/参照
acf_form() – advancedcustomfields.com
