我有一个网站使用自定义元框,其中包含使用Meta-Box插件的以下字段。代码如下 `
$meta_boxes[] = array(
'title' => 'MLS ID',
'pages' => array('property'),
'fields' => array(
array(
'name' => 'MLS ID',
'id' => "IntegratorPropertyID",
'desc' => 'MLS: e.g. 240091025-217',
'type' => 'text',
),
array(
'name' => 'Test MLS',
'id' => "mlsTest",
'desc' => 'Test MLS for Duplicate',
'type' => 'button',
),
),
'validation' => array(
'rules' => array(
"IntegratorPropertyID" => array(
'required' => true
),
),
'messages' => array(
"IntegratorPropertyID" => array(
'required' => 'MLS is required',
),
)
)
);
现在我要找的是添加一个'add_action( 'save_post', 'checkMLS' );
'函数,它检查所有以前的CPT属性是否有MLS号,以确保之前没有输入过。我使用的代码是:
function checkMLS( $post_id ) {
$slug = 'property';
if ( $slug != $_POST['post_type'] ) {
return;
}
$mls2 = rwmb_meta('IntegratorPropertyID', 'type=text', $post_id);
$args = array( 'post_type' => 'property' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$this1 = get_the_ID();
$mls1 = rwmb_meta('IntegratorPropertyID', 'type=text', $this1);
if ( $mls2 == $mls1 ) {
$my_post = array(
'ID' => $post_id,
'IntegratorPropertyID' => 'DUPLICATE!'
);
wp_update_post($my_post);
return;
}
endwhile;
}
add_action( 'save_post', 'checkMLS' );
该代码可在functions.php中找到,当我尝试发布屏幕时会变白。调试模式也没有提供任何帮助。 :/
我确定我正在制作一些编程重大错误。有人能说出来吗?或者指点我正确的方向?或建议完全不同的东西?
由于 基思
答案 0 :(得分:1)
行。首先,您的白页没有指示原因,可能是“内存不足”错误,或者是“php'最长执行时间”错误。这可以从checkMLS()
函数的工作方式中的一个主要缺陷中获益。缺点是您实际上在数据库中的所有'property'
帖子中循环。根据数据集的大小,这可能很多,特别是考虑到您正在处理MLS列表。
我的推荐:
弄清楚rwmb_meta()
函数如何抓取它的信息。它可能只是get_post_meta()
函数的包装函数,但可能不是。假设它是,我建议做以下几点,我将在后面和评论中详细解释:
// the save_post action runs after a post has been saved/created, and has two parameters
// param 1: the id of the post
// param 2: the post object
function checkMLS($post_id, $post) {
// use the post object post_type to determine if this is a property or not.
// it will be a lot more reliable
if ($post->post_type != 'property') return;
// meta_key should be equal to the 'meta_key' field in the wp_postmeta table, for the
// id you are trying to check against. your example used IntegratorPropertyID.
// again you may want to check rwmb_meta() function to figure out if there is a
// 'prefix' or 'suffix' added to this. despite that, it is almost certainly going to
// be looking in the wp_postmeta table, so this should work nicely
$meta_key = 'IntegratorPropertyID';
// look up the current mls id for this post, which you just saved/created
$mls_id = get_post_meta($post_id, $meta_key, true);
// lookup in the actual database table for any matching row, that has the same MLS id
// that is not this post.
global $wpdb;
$q = $wpdb->prepare('select post_id from '.$wpdb->postmeta.' where meta_key = %s and meta_value = %s and post_id != %d limit 1', $meta_key, $mls_id, $post_id);
$exists = $wpdb->get_var($q);
// if it already exists, mark the value as a duplicate
if ($exists) update_post_meta($post_id, $meta_key, 'DUPLICATE!');
}
// add your check function late in the actions, at priority 10000
add_action('save_post', 'checkMLS', 10000, 2);
从顶部开始,我们使用两个参数创建回调,因为save_post
操作会发送两个$post_id
和$post
。由于save_post在保存帖子之后运行,因此您已经有一个对象($post
),其中包含所有帖子信息。然后我们可以使用$post
对象来确定帖子的类型,这比查看$_REQUEST
值更可靠,主要是因为$post
直接从数据库中提取并传递给你。
现在,如前所述,我假设rwmb_meta()
只是get_post_meta()
的一个包装函数。它可能会为$meta_key
添加前缀或后缀,但对rwmb_meta()
函数的一点研究应告诉您$meta_key
在将其传递给get_post_meta()
函数时如何更改,你可以从那里修改$meta_key
。使用正确的$meta_key
,我们现在可以获取刚刚保存的属性的MLS ID。
使用该MLS id,我们需要在数据库中进行直接查找,以确定是否还有另一个具有该ID的属性。虽然您的演示函数中的方式可以处理小型数据集,但它无法在任何可观数量的属性上工作。因此需要直接方法。我们只需编写一些特殊的SQL来查看wp_postmeta
表中任何post_id
,其中MLS id等于为此属性输入的MLS id,而不是此属性。如果我们找到一个不是这个属性的匹配,那么它就是一个骗局。如果是骗局,我们需要将其标记为欺骗。
请注意,此解决方案根本不执行任何循环。它没有可能循环超过10000条记录来查找重复ID。这是精简的。它直接在db中查找id,以查看是否有重复。
希望这对您有所帮助,并希望其他人也觉得有用。我的公司几乎完全按照WordPress的方式工作。通过我们与WordPress合作多年,我们遇到了从超级简单到过度复杂的问题。在不同的环境中,同样的问题也体现在我们的许多客户身上。这个解决方案虽然高度定制,但很简单。然而,它会起作用。