【问题标题】:Check for duplicate Wordpress Post with Custom Meta Data on Publish在发布时检查具有自定义元数据的重复 Wordpress 帖子
【发布时间】:2013-12-20 18:04:41
【问题描述】:

我有一个使用自定义元框的站点,该站点使用 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 中,当我尝试发布时屏幕变白。调试模式也不提供任何帮助。 :/

我确定我在某处犯了一些编程重大错误。有人可以指出吗?或者也许指出我正确的方向?或提出完全不同的建议?

谢谢 基思

【问题讨论】:

    标签: php wordpress metadata custom-post-type


    【解决方案1】:

    好的。首先,您的白页没有说明原因,可能是“内存不足”错误或 php“最大执行时间”错误。这源于checkMLS() 函数工作方式的一个主要缺陷。缺陷是您实际上是在循环浏览数据库中的所有'property' 帖子。根据数据集的大小,这可能会很多,尤其是考虑到您正在处理 MLS 列表。

    我的建议:

    弄清楚rwmb_meta() 函数是如何获取它的信息的。它可能只是 get_post_meta() 函数的包装函数,但可能不是。假设是这样,我建议做以下,我将解释 after 以及 cmets 中的细节:

    // 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 表中查找任何具有 MLS id 的 post_id,该 MLS id 等于为此属性输入的 ID,而不是此属性。如果我们找到一个不是这个属性的匹配,那么它就是一个骗子。如果是骗子,我们需要将其标记为骗子。

    请注意,此解决方案根本不进行任何循环。它不可能循环超过 10000 条记录来查找 dup id。这是精简的。它直接在db中查找id,看是否有dups。

    希望这对您有帮助,也希望其他人也觉得它有帮助。我的公司几乎只做 WordPress 的工作。通过我们多年使用 WordPress 的工作,我们遇到了从超级简单到过于复杂的问题。同样的问题,在不同的环境中,已经体现在我们的许多客户身上。这个解决方案简单明了,虽然是高度定制的。但是,它会起作用。

    【讨论】:

    • 感谢这就像一个魅力:) 对不起,我从来没有回复
    猜你喜欢
    • 1970-01-01
    • 2013-01-13
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多