Custom Field Suite で 選択肢 を全て取得する方法

WordPressのプラグインで Custom Field Suite や Advanced Custom Fields は良く使うと思います。

理由は特になく、当方は Custom Field Suite (以下CFS) をメインに使っておりますが、先日このCFSを使った投稿で、抽出システムを作る必要があったので調べていたら【選択肢】いわゆるSELECTを使った投稿を抽出する際、CFSで設定した選択肢をすべて取得する物がありませんでした。

少し調べた感じだと Advanced Custom Fields ではそういったニーズにも対応しているようでしたが、今さら入れ替えるのも面倒臭かったので適当に作ってみました。

実現するには以下の条件が必要です。
・選択肢のKEYになる部分にユニークなPREFIX + 数字1文字以上

CFSの設定画面

KEY:VALUE という構成になってます。

functions.phpに下記コードを追加

function cfs_select_get_field($prefix) {
	global $wpdb;
	$result = $wpdb->get_var("select meta_value from wp_postmeta where meta_key='cfs_fields';");
	preg_match_all("/\"(".$prefix.".+?)\";s:\d{1,}:\"(.+?)\"/", $result, $match);
	return $match;
}

※説明:CFSの設定情報はすべて wp_postmeta の meta_key=cfs_fieldsにシリアライズしたものが格納されているので、それを引き出し正規表現で必要なKEYとVALUEをマッチさせてます。

呼び出し側 cfs_select_get_field(PREFIX)

$res = cfs_select_get_field('p_');
foreach ($res[0] as $key => $val) {
	echo '<dd><input type="checkbox" value="'.$res[1][$key].'" id="'.$res[1][$key].'"><label for="'.$res[1][$key].'">'.$res[2][$key].'</label></dd>'."\r\n";
}

※説明:正規表現でマッチしたものをループで処理してます。配列は [0]全文 [1]KEY [2]VALUE で格納されています。

とりあえず綺麗なコードではないですが、シンプルに構成してみました。
余計なループ処理も抑えて書いています。
これでCFSで選択肢を増やしても連動して抽出フォームに項目が追加されます。

SQL SERVER + MS Access + ストアド プロシージャ

今回はSQL SERVERのストアドプロシージャを手軽に使う方法です。
あまり利用するケースが少ないですが、レアケースがあった場合に便利です。

プログラミング的なことをストアドプロシージャでやろうとすると結構面倒くさいので、今回はVBA(MS Access)側でSQL SERVER向けのSQLを生成し、SQL SERVER側でSQLを処理する形です。

ストアドプロシージャーの記述

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER PROCEDURE [dbo].[svr_query]
	@sql text
AS
BEGIN
	exec (@sql)
END

VBAの記述

Dim ws As DAO.Workspace
Dim db As DAO.Database
Dim tb As DAO.Recordset
Dim sql as String

sql = "select * from dbo.TEST where COL_A='サンプルテキスト';"
sql = Replace(sql, "'", "''")

Set ws = DBEngine.Workspaces(0)
Set db = ws.OpenDatabase("", False, False, "ODBC;DSN=●●●●;UID=●●●;PWD=●●●;")
Set tb = db.OpenRecordset("EXECUTE svr_query '" & sql & "'", dbOpenSnapshot, dbSQLPassThrough)

If tb.RecordCount > 0 Then
    Do Until tb.EOF
        *****取得したデータの処理*****
        tb.MoveNext
    Loop
End If

※途中、sqlのシングルクォーテーションを二重に置換してますが、こうしないとSQL SERVER側でSQLが実行されません。
また、この方法を用いることで、データベースが別の場合もシンプルなSQLで対応することが可能です。