在发布时检查带有自定义元数据的重复Wordpress帖子

时间:2013-12-20 18:04:42

标签: php wordpress metadata custom-post-type

我有一个网站使用自定义元框,其中包含使用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中找到,当我尝试发布屏幕时会变白。调试模式也没有提供任何帮助。 :/

我确定我正在制作一些编程重大错误。有人能说出来吗?或者指点我正确的方向?或建议完全不同的东西?

由于 基思

1 个答案:

答案 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合作多年,我们遇到了从超级简单到过度复杂的问题。在不同的环境中,同样的问题也体现在我们的许多客户身上。这个解决方案虽然高度定制,但很简单。然而,它会起作用。