来自自定义元数据库的自定义帖子元被随机删除

时间:2022-01-26 作者:Tony Djukic

一段时间以来,我一直在应用和更新一些公司在不同网站上重复使用的自定义元数据库。(不同的代谢箱,但方法相同。)

本质上,它允许将不同自定义帖子类型的单个帖子与默认WP页面和帖子进行“关联”。

比如说Post ID = 449 这是一个Post Type = CustomA 可以分配给任何页面或帖子。

我所做的一切都很有效。它已经工作了很长时间了。它仍然有效。

然而,我们开始看到的是,在奇怪的情况下,其中一个页面/帖子将看到所有自定义帖子元从页面中清除。

我自己从来都无法复制这个错误。我只得到了URL,可以编辑自定义帖子元所在的帖子或页面的屏幕,现在它不见了。

我曾多次尝试在监视开发人员控制台时强制解决问题,并尝试触发一些可以使其发生的事情,但我无法触发它。

错误日志为空。(每隔几天就会有一个奇怪的警告,但与讨论中的任何帖子或功能无关。)

<?php
    //ADD CPT SELECTION METABOX TO PAGES AND POSTS
    function cpt_add_cpt_selection() {
        $screens = [\'page\', \'post\'];
        foreach( $screens as $screen ) {
            add_meta_box(
                \'cpt_assignment\',
                \'Assign A Custom Post Type\',
                \'cpt_assign_metabox\',
                $screen,
                \'side\',
                \'low\',
                 array(
                    \'__block_editor_compatible_meta_box\' => true,
                    \'__back_compat_meta_box\'             => false,
                )
            );
        }
    }
    add_action( \'add_meta_boxes\', \'cpt_add_cpt_selection\' );
    //QUICK LINKS SELECTION METABOX OPTIONS
    function cpt_assign_metabox( $post ) {
        wp_nonce_field( basename( __FILE__ ), \'cpt_nonce\' );
        $cpt_position               = get_post_meta( $post->ID, \'cpt_position\', true );
        $cpt_appended_cpts          = get_post_meta( $post->ID, \'cpt_cpts\', false );
        ?>
        <label for="cpt_position_sidebar" style="display:block;margin-bottom:0.5rem;">
            <input type="radio" id="cpt_position_sidebar" name="cpt_position" value="sidebar" <?php checked( \'sidebar\' == $cpt_position ); ?>/> Display in Sidebar
        </label>
        <label for="cpt_position_content" style="display:block;margin-bottom:0.5rem;">
            <input type="radio" id="cpt_position_content" name="cpt_position" value="content" <?php checked( \'content\' == $cpt_position ); ?>/> Display below Content
        </label>
        <select id="cpt_cpts" name="cpt_cpts[]" multiple="multiple" style="width:90%;">
        <?php
        if( $cpt_appended_cpts ) {
            foreach( $cpt_appended_cpts as $cpt_ids ) {
                foreach( $cpt_ids as $cpt_id ) {
                    $cpt_title = get_the_title( $cpt_id );
                    $cpt_title = ( mb_strlen( $cpt_title ) > 50 ) ? mb_substr( $cpt_title, 0, 49 ) . \'...\' : $cpt_title;
                    echo \'<option value="\' . $cpt_id . \'" selected="selected">\' . $cpt_title . \'</option>\';
                }
            }
        }
        ?>
        </select>
    <?php }
    //SAVE THE CPT ASSIGNMENT FIELDS TO POSTS AND PAGES.
    function cpt_assign_save_postdata( $post_id ) {
        if( isset( $_POST[\'cpt_cpts\'] ) ) {
            update_post_meta( $post_id, \'cpt_cpts\', $_POST[\'cpt_cpts\'] );
        } else {
            delete_post_meta( $post_id, \'cpt_cpts\' );
        }
        if( isset( $_POST[\'cpt_position\'] ) ) {
            update_post_meta( $post_id, \'cpt_position\', $_POST[\'cpt_position\'] );
        } else {
            delete_post_meta( $post_id, \'cpt_position\' );
        }
    }
    add_action( \'save_post\', \'cpt_assign_save_postdata\' );
    //AJAX QUERY FOR POSTS USING SELECT2
    function cpt_get_cpts_ajax_callback() {
        $return = array();
        $search_results = new WP_Query( array(
            \'s\'                     => $_GET[\'q\'],
            \'post_type\'             => \'the_custom_cpt_in_question\',
            \'post_status\'           => \'publish\',
            \'ignore_sticky_posts\'   => 1,
            \'posts_per_page\'        => -1
        ) );
        if( $search_results->have_posts() ) :
            while( $search_results->have_posts() ) : $search_results->the_post();
                $title = ( mb_strlen( $search_results->post->post_title ) > 50 ) ? mb_substr( $search_results->post->post_title, 0, 49 ) . \'...\' : $search_results->post->post_title;
                $return[] = array( $search_results->post->ID, $title );
            endwhile;
        endif;
        echo json_encode( $return );
        wp_die();
    }
    add_action( \'wp_ajax_getcustompt\', \'cpt_get_cpts_ajax_callback\' );
就像我说的,它实际上在起作用。每天,在许多大型网站上,人们都在添加和删除一些与不同帖子和页面关联的自定义帖子类型。CPT本身是“FAQ”或“团队成员”之类的东西,使用的主题应用了模板标记,如果有CPT分配给页面,则会显示CPT的内容。一切正常。

一个异常情况是,可能每3-4周一次,一个填充了这些字段的页面(包括指定内容是否应应用于侧栏或内容下方的字段)会从Posteta表中清除。

(使用两个不同的模板标记,在检索任何内容之前运行条件检查,以确定分配的CPT是应显示在侧栏中还是应显示在内容下方。)

我的两个理论都是我无法复制的:

在“更新”过程完成之前,用户正在离开页面。但我一直在尝试,每次我这样做,页面仍然有自定义的帖子元。

我们使用WPML,人们会打开多个标签页,而且通常会使用不同的语言(我们所有的客户端网站都是双语的),我注意到这有时会导致后端的事情变得混乱。。。您开始使用一种语言进行编辑,用另一种语言检查新选项卡中的内容,返回到您正在编辑的第一页,您的搜索不再工作,因为搜索是用您最近打开的选项卡的语言执行的,该选项卡设置了语言cookie。

所以,我的问题是,是否有人在我的元数据库和保存过程中看到了可能导致偶尔清除帖子/页面上的Posteta的内容?

(耐心等待SallyCJ.。-P)

P、 我知道有一种不同的方法来构建这些元数据库,我也正计划这样做,但以我目前的工作量,我没有时间停止新项目的工作,重新审视表面上有效的东西。我也不知道使用新的基于反应的代谢箱是否能解决我们间歇性遇到的问题。

1 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

代码使用save_post 钩子来保存表单的结果,但是,它从未检查要保存的帖子。

这意味着您的保存功能可以为该帖子运行,但也可以为草稿、自动保存等运行

除此之外,还有如下检查:

        if( isset( $_POST[\'cpt_cpts\'] ) ) {
            update_post_meta( $post_id, \'cpt_cpts\', $_POST[\'cpt_cpts\'] );
        } else {
            delete_post_meta( $post_id, \'cpt_cpts\' );
        }
如果cpt_cpts 未定义它将删除帖子元,从而导致您遇到的问题。这是不正确的,cpt_cpts 没有定义并不意味着cpt_cpts 需要删除。这可能不是提交post表单,而是对不相关的代码(如插件)的一个小更新。

复制此内容的快速方法应该是使用快速编辑功能,这将更新帖子,即使您选择的输入不在页面上或更新过程的一部分。

相反,保存处理程序还需要检查这一点,例如,通过检查nonce是否存在,或者是否存在其他表单输入,以及要保存的帖子的帖子类型和其他详细信息。

相关推荐

如何在WordPress开发中添加带有ACF自定义字段ID的自定义metabox字段

我是wordpress开发的新手,我在我的项目中安装了高级自定义字段插件,并创建了两个文本字段名称&;我还创建了一个插件,可以在帖子中创建一个带有文本框的元框。现在在帖子中,我将获得自定义字段名称(&A);电子邮件和我的自定义元框旁边将出现,但我必须将我的元框附加到名称字段旁边,即在名称字段和电子邮件字段之间。我的metabox代码如下。请任何人帮帮我//Creating the custom meta box function my_notice_meta_box() {