wordpress 如何在WooCommerce订阅插件中添加订阅的自定义字段,而不接触核心文件?

f87krz0w  于 2023-03-17  发布在  WordPress
关注(0)|答案(2)|浏览(217)

我正在使用WooCommerce订阅来管理我的WordPress网站上的经常性付款,该网站销售婴儿尿布。
我想向我的订阅添加更多详细信息,以便我的客户可以通过订阅ID以外的其他方式来区分他们的订阅。
我在客户旅程开始时以一种形式捕捉关于客户婴儿的线索,包括他们的名字。
为了向订阅数据中添加额外的详细信息字段,我修改了位于以下位置的wcs_create_subscription函数:
wp-content/plugins/woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/wcs-functions.php
首先向$default_args数组添加一个'baby_name'参数,我已经设置了该数组,以便使用get_current_user_id()存储当前用户ID,只是为了测试功能:

$default_args = array(
    'status'             => '',
    'baby_name'          => get_current_user_id(),
    'order_id'           => 0,
    'customer_note'      => null,
    'customer_id'        => ( ! empty( $order ) ) ? $order->get_user_id() : null,
    'start_date'         => $default_start_date,
    'date_created'       => $now,
    'created_via'        => ( ! empty( $order ) ) ? wcs_get_objects_property( $order, 'created_via' ) : '',
    'order_version'      => ( ! empty( $order ) ) ? wcs_get_objects_property( $order, 'version' ) : WC_VERSION,
    'currency'           => ( ! empty( $order ) ) ? wcs_get_objects_property( $order, 'currency' ) : get_woocommerce_currency(),
    'prices_include_tax' => ( ! empty( $order ) ) ? ( ( wcs_get_objects_property( $order, 'prices_include_tax' ) ) ? 'yes' : 'no' ) : get_option( 'woocommerce_prices_include_tax' ), // we don't use wc_prices_include_tax() here because WC doesn't use it in wc_create_order(), not 100% sure why it doesn't also check the taxes are enabled, but there could forseeably be a reason
);

然后,我运行一个update_post_meta()函数,将参数保存在订阅数据库中:
update_post_meta( $subscription_id, '_baby_name', $args['baby_name'] );
下面是完整的wcs_create_subscription函数:

/**
 * Create a new subscription
 *
 * Returns a new WC_Subscription object on success which can then be used to add additional data.
 *
 * @return WC_Subscription | WP_Error A WC_Subscription on success or WP_Error object on failure
 * @since  2.0
 */
function wcs_create_subscription( $args = array() ) {

    $now   = gmdate( 'Y-m-d H:i:s' );
    $order = ( isset( $args['order_id'] ) ) ? wc_get_order( $args['order_id'] ) : null;

    if ( ! empty( $order ) ) {
        $default_start_date = wcs_get_datetime_utc_string( wcs_get_objects_property( $order, 'date_created' ) );
    } else {
        $default_start_date = ( isset( $args['date_created'] ) ) ? $args['date_created'] : $now;
    }

    $default_args = array(
        'status'             => '',
        'baby_name'          => get_current_user_id(),
        'order_id'           => 0,
        'customer_note'      => null,
        'customer_id'        => ( ! empty( $order ) ) ? $order->get_user_id() : null,
        'start_date'         => $default_start_date,
        'date_created'       => $now,
        'created_via'        => ( ! empty( $order ) ) ? wcs_get_objects_property( $order, 'created_via' ) : '',
        'order_version'      => ( ! empty( $order ) ) ? wcs_get_objects_property( $order, 'version' ) : WC_VERSION,
        'currency'           => ( ! empty( $order ) ) ? wcs_get_objects_property( $order, 'currency' ) : get_woocommerce_currency(),
        'prices_include_tax' => ( ! empty( $order ) ) ? ( ( wcs_get_objects_property( $order, 'prices_include_tax' ) ) ? 'yes' : 'no' ) : get_option( 'woocommerce_prices_include_tax' ), // we don't use wc_prices_include_tax() here because WC doesn't use it in wc_create_order(), not 100% sure why it doesn't also check the taxes are enabled, but there could forseeably be a reason
    );

    $args              = wp_parse_args( $args, $default_args );
    $subscription_data = array();

    // Validate the date_created arg.
    if ( ! is_string( $args['date_created'] ) || false === wcs_is_datetime_mysql_format( $args['date_created'] ) ) {
        return new WP_Error( 'woocommerce_subscription_invalid_date_created_format', _x( 'Invalid created date. The date must be a string and of the format: "Y-m-d H:i:s".', 'Error message while creating a subscription', 'woocommerce-subscriptions' ) );
    } elseif ( wcs_date_to_time( $args['date_created'] ) > current_time( 'timestamp', true ) ) {
        return new WP_Error( 'woocommerce_subscription_invalid_date_created', _x( 'Subscription created date must be before current day.', 'Error message while creating a subscription', 'woocommerce-subscriptions' ) );
    }

    // Validate the start_date arg.
    if ( ! is_string( $args['start_date'] ) || false === wcs_is_datetime_mysql_format( $args['start_date'] ) ) {
        return new WP_Error( 'woocommerce_subscription_invalid_start_date_format', _x( 'Invalid date. The date must be a string and of the format: "Y-m-d H:i:s".', 'Error message while creating a subscription', 'woocommerce-subscriptions' ) );
    }

    // check customer id is set
    if ( empty( $args['customer_id'] ) || ! is_numeric( $args['customer_id'] ) || $args['customer_id'] <= 0 ) {
        return new WP_Error( 'woocommerce_subscription_invalid_customer_id', _x( 'Invalid subscription customer_id.', 'Error message while creating a subscription', 'woocommerce-subscriptions' ) );
    }

    // check the billing period
    if ( empty( $args['billing_period'] ) || ! in_array( strtolower( $args['billing_period'] ), array_keys( wcs_get_subscription_period_strings() ) ) ) {
        return new WP_Error( 'woocommerce_subscription_invalid_billing_period', __( 'Invalid subscription billing period given.', 'woocommerce-subscriptions' ) );
    }

    // check the billing interval
    if ( empty( $args['billing_interval'] ) || ! is_numeric( $args['billing_interval'] ) || absint( $args['billing_interval'] ) <= 0 ) {
        return new WP_Error( 'woocommerce_subscription_invalid_billing_interval', __( 'Invalid subscription billing interval given. Must be an integer greater than 0.', 'woocommerce-subscriptions' ) );
    }

    $subscription_data['post_type']     = 'shop_subscription';
    $subscription_data['post_status']   = 'wc-' . apply_filters( 'woocommerce_default_subscription_status', 'pending' );
    $subscription_data['ping_status']   = 'closed';
    $subscription_data['post_author']   = 1;
    $subscription_data['post_password'] = uniqid( 'order_' );
    // translators: Order date parsed by strftime
    $post_title_date = strftime( _x( '%b %d, %Y @ %I:%M %p', 'Used in subscription post title. "Subscription renewal order - <this>"', 'woocommerce-subscriptions' ) ); // phpcs:ignore WordPress.WP.I18n.UnorderedPlaceholdersText
    // translators: placeholder is order date parsed by strftime
    $subscription_data['post_title']    = sprintf( _x( 'Subscription &ndash; %s', 'The post title for the new subscription', 'woocommerce-subscriptions' ), $post_title_date );
    $subscription_data['post_date_gmt'] = $args['date_created'];
    $subscription_data['post_date']     = get_date_from_gmt( $args['date_created'] );

    if ( $args['order_id'] > 0 ) {
        $subscription_data['post_parent'] = absint( $args['order_id'] );
    }

    if ( ! is_null( $args['customer_note'] ) && ! empty( $args['customer_note'] ) ) {
        $subscription_data['post_excerpt'] = $args['customer_note'];
    }

    // Only set the status if creating a new subscription, use wcs_update_subscription to update the status
    if ( $args['status'] ) {
        if ( ! in_array( 'wc-' . $args['status'], array_keys( wcs_get_subscription_statuses() ) ) ) {
            return new WP_Error( 'woocommerce_invalid_subscription_status', __( 'Invalid subscription status given.', 'woocommerce-subscriptions' ) );
        }
        $subscription_data['post_status']  = 'wc-' . $args['status'];
    }

    $subscription_id = wp_insert_post( apply_filters( 'woocommerce_new_subscription_data', $subscription_data, $args ), true );

    if ( is_wp_error( $subscription_id ) ) {
        return $subscription_id;
    }

    // Default order meta data.
    update_post_meta( $subscription_id, '_order_key', wcs_generate_order_key() );
    update_post_meta( $subscription_id, '_order_currency', $args['currency'] );
    update_post_meta( $subscription_id, '_prices_include_tax', $args['prices_include_tax'] );
    update_post_meta( $subscription_id, '_created_via', sanitize_text_field( $args['created_via'] ) );

    // add/update the billing
    update_post_meta( $subscription_id, '_billing_period', $args['billing_period'] );
    update_post_meta( $subscription_id, '_billing_interval', absint( $args['billing_interval'] ) );

    update_post_meta( $subscription_id, '_customer_user', $args['customer_id'] );
    update_post_meta( $subscription_id, '_order_version', $args['order_version'] );

    update_post_meta( $subscription_id, '_schedule_start', $args['start_date'] );
    update_post_meta( $subscription_id, '_baby_name', $args['baby_name'] );

    /**
     * Filter the newly created subscription object.
     *
     * @since 2.2.22
     * @param WC_Subscription $subscription
     */
    $subscription = apply_filters( 'wcs_created_subscription', wcs_get_subscription( $subscription_id ) );

    /**
     * Triggered after a new subscription is created.
     *
     * @since 2.2.22
     * @param WC_Subscription $subscription
     */
    do_action( 'wcs_create_subscription', $subscription );

    return $subscription;
}

我可以确认这是可行的,因为我可以看到一行的 meta_key字段中有_baby_name,meta_value字段中有我的用户ID,我最近将ID 2898放置在我的站点_postmeta数据库表中:

因为我知道我不应该修改核心插件文件,我希望我的修改在一个片段或类似的,我可以放置在我的子主题function.php文件.任何建议?

1tu0hz3e

1tu0hz3e1#

从您发布的代码中可以推断出可以使用wcs_create_subscription action钩子:

/**
 * Triggered after a new subscription is created.
 *
 * @since 2.2.22
 * @param WC_Subscription $subscription
 */
function action_wcs_create_subscription( $subscription ) {
    // Get ID
    $subscription_id = $subscription->get_id();

    update_post_meta( $subscription_id, '_baby_name', 'my_value' );
}
add_action( 'wcs_create_subscription', 'action_wcs_create_subscription', 10, 1 );

不需要先将其添加为参数。如果需要,可以通过$subscription获取多个数据

cu6pst1q

cu6pst1q2#

随着WooCommerce 7.3的新HPOS功能,不再建议使用post meta。您应该用途:

$subscription->update_meta_data( '_baby_name', 'my_value' );
$subscription->save();

其中$subscription为订阅来的对象,如果没有加载,可以使用函数:

$subscription = wcs_get_subscription( $sub_id );

相关问题