Woocommerce预订:致命错误:在非对象上调用成员函数has_persons()

时间:2015-05-29 12:10:17

标签: wordpress-plugin woocommerce wordpress

我需要你在WordPress和woocommerce上的出色技能,我有一个问题,我不知道为什么woocommerce预订抛出这个:

**Fatal error: Call to a member function `has_persons()` on a non-object in `xxx/plugins/woocommerce-bookings/includes/class-wc-booking.php` on line 557**

并停止所有脚本执行。

woocommerce预订类:

<?php

/ ** *所有预订的主要模型类,它处理所有数据 * / WC_Booking {

/** @public int */
public $id;

/** @public string */
public $booking_date;

/** @public string */
public $start;

/** @public string */
public $end;

/** @public bool */
public $all_day;

/** @public string */
public $modified_date;

/** @public object */
public $post;

/** @public int */
public $product_id;

/** @public object */
public $product;

/** @public int */
public $order_id;

/** @public object */
public $order;

/** @public int */
public $customer_id;

/** @public string */
public $status;

/** @public array - contains all post meta values for this booking */
public $custom_fields;

/** @public bool */
public $populated;

/** @private array - used to temporarily hold order data for new bookings */
private $order_data;

/**
 * Constructor, possibly sets up with post or id belonging to existing booking
 * or supplied with an array to construct a new booking
 * @param int/array/obj $booking_data
 */
public function __construct( $booking_data = false ) {
    $populated = false;

    if ( is_array( $booking_data ) ) {
        $this->order_data = $booking_data;
        $populated = false;
    } else if ( is_int( intval( $booking_data ) ) && 0 < $booking_data ) {
        $populated = $this->populate_data( $booking_data );
    } else if ( is_object( $booking_data ) && isset( $booking_data->ID ) ) {
        $this->post = $booking_data;
        $populated = $this->populate_data( $booking_data->ID );
    }

    $this->populated = $populated;
}

/**
 * Actual create for the new booking belonging to an order
 * @param string Status for new order
 */
public function create( $status = 'unpaid' ) {
    $this->new_booking( $status, $this->order_data );
    $this->schedule_events();
}

/**
 * Schedule events for this booking
 */
public function schedule_events() {
    switch ( get_post_status( $this->id ) ) {
        case "paid" :
            if ( $this->start && $this->get_order() ) {
                $order_status = $this->get_order()->get_status();

                if ( ! in_array( $order_status, array( 'cancelled', 'refunded', 'pending', 'on-hold' ) ) ) {
                    wp_schedule_single_event( strtotime( '-' . absint( apply_filters( 'woocommerce_bookings_remind_before_days', 1 ) ) . ' day', $this->start ), 'wc-booking-reminder', array( $this->id ) );
                }
            }
            if ( $this->end ) {
                wp_schedule_single_event( $this->end, 'wc-booking-complete', array( $this->id ) );
            }
        break;
        default :
            wp_clear_scheduled_hook( 'wc-booking-reminder', array( $this->id ) );
            wp_clear_scheduled_hook( 'wc-booking-complete', array( $this->id ) );
        break;
    }
}

/**
 * Makes the new booking belonging to an order
 * @param string $status The status for this new booking
 * @param array $order_data Array with all the new order data
 */
private function new_booking( $status, $order_data ) {
    global $wpdb;

    $order_data = wp_parse_args( $order_data, array(
        'user_id'           => 0,
        'resource_id'       => '',
        'product_id'        => '',
        'order_item_id'     => '',
        'persons'           => array(),
        'cost'              => '',
        'start_date'        => '',
        'end_date'          => '',
        'all_day'           => 0,
        'parent_id'         => 0,
    ) );

    // Get parent data
    if ( $order_data['parent_id'] ) {
        if ( ! $order_data['order_item_id'] ) {
            $order_data['order_item_id'] = get_post_meta( $order_data['parent_id'], '_booking_order_item_id', true );
        }

        if ( ! $order_data['user_id'] ) {
            $order_data['user_id'] = get_post_meta( $order_data['parent_id'], '_booking_customer_id', true );
        }
    }

    // Get order ID from order item
    if ( $order_data['order_item_id'] ) {
        $order_id = $wpdb->get_var( $wpdb->prepare( "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $order_data['order_item_id'] ) );
    } else {
        $order_id = 0;
    }

    $booking_data = array(
        'post_type'   => 'wc_booking',
        'post_title'  => sprintf( __( 'Booking &ndash; %s', 'woocommerce-bookings' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Booking date parsed by strftime', 'woocommerce-bookings' ) ) ),
        'post_status' => $status,
        'ping_status' => 'closed',
        'post_parent' => $order_id
    );

    $this->id = wp_insert_post( $booking_data );

    // Setup the required data for the current user
    if ( ! $order_data['user_id'] ) {
        if ( is_user_logged_in() ) {
            $order_data['user_id'] = get_current_user_id();
        } else {
            $order_data['user_id'] = 0;
        }
    }

    // Convert booking start and end to requried format
    if ( is_numeric( $order_data['start_date'] ) ) {
        // Convert timestamp
        $order_data['start_date'] = date( 'YmdHis', $order_data['start_date'] );
        $order_data['end_date']   = date( 'YmdHis', $order_data['end_date'] );
    } else {
        $order_data['start_date'] = date( 'YmdHis', strtotime( $order_data['start_date'] ) );
        $order_data['end_date']   = date( 'YmdHis', strtotime( $order_data['end_date'] ) );
    }

    $meta_args = array(
        '_booking_order_item_id' => $order_data['order_item_id'],
        '_booking_product_id'    => $order_data['product_id'],
        '_booking_resource_id'   => $order_data['resource_id'],
        '_booking_persons'       => $order_data['persons'],
        '_booking_cost'          => $order_data['cost'],
        '_booking_start'         => $order_data['start_date'],
        '_booking_end'           => $order_data['end_date'],
        '_booking_all_day'       => intval( $order_data['all_day'] ),
        '_booking_parent_id'     => $order_data['parent_id'],
        '_booking_customer_id'   => $order_data['user_id'],
    );

    foreach ( $meta_args as $key => $value ) {
        update_post_meta( $this->id, $key, $value );
    }

    WC_Cache_Helper::get_transient_version( 'bookings', true );

    do_action( 'woocommerce_new_booking', $this->id );
}

/**
 * Assign this booking to an order and order item by ID
 * @param int $order_id
 * @param int $order_item_id
 */
public function set_order_id( $order_id, $order_item_id ) {
    $this->order_id = $order_id;
    wp_update_post( array( 'ID' => $this->id, 'post_parent' => $this->order_id ) );
    update_post_meta( $this->id, '_booking_order_item_id', $order_item_id );
}

/**
 * Populate the data with the id of the booking provided
 * Will query for the post belonging to this booking and store it
 * @param int $booking_id
 */
public function populate_data( $booking_id ) {
    if ( ! isset( $this->post ) ) {
        $post = get_post( $booking_id );
    }

    if ( is_object( $post ) ) {
        // We have the post object belonging to this booking, now let's populate
        $this->id            = $post->ID;
        $this->booking_date  = $post->post_date;
        $this->modified_date = $post->post_modified;
        $this->customer_id   = $post->post_author;
        $this->custom_fields = get_post_meta( $this->id );
        $this->status        = $post->post_status;
        $this->order_id      = $post->post_parent;

        // Define the data we're going to load: Key => Default value
        $load_data = array(
            'product_id'  => '',
            'resource_id' => '',
            'persons'     => array(),
            'cost'        => '',
            'start'       => '',
            'customer_id' => '',
            'end'         => '',
            'all_day'     => 0,
            'parent_id'   => 0,
        );

        // Load the data from the custom fields (with prefix for this plugin)
        $meta_prefix = '_booking_';

        foreach ( $load_data as $key => $default ) {
            if ( isset( $this->custom_fields[ $meta_prefix . $key ][0] ) && $this->custom_fields[ $meta_prefix . $key ][0] !== '' ) {
                $this->$key = maybe_unserialize( $this->custom_fields[ $meta_prefix . $key ][0] );
            } else {
                $this->$key = $default;
            }
        }

        // Start and end date converted to timestamp
        $this->start = strtotime( $this->start );
        $this->end   = strtotime( $this->end );

        // Save the post object itself for future reference
        $this->post = $post;
        return true;
    }

    return false;
}

/**
 * Will change the booking status once the order is paid for
 * @return bool
 */
public function paid() {
    $current_status = $this->status;
    $event          = wp_get_schedule( 'wc-booking-reminder', array( $this->id ) );

    if ( $this->populated && in_array( $current_status, array( 'unpaid', 'confirmed' ) ) ) {
        $this->update_status( 'paid' );

        if ( ! empty( $event ) ) {
            $this->schedule_events();
        }

        return true;
    }

    return false;
}

/**
 * Set the new status for this booking
 * @param string $status
 * @return bool
 */
public function update_status( $status ) {
    $current_status   = $this->get_status( true );
    $allowed_statuses = array( 'unpaid', 'pending-confirmation', 'confirmed', 'paid', 'cancelled', 'complete', 'in-cart', 'was-in-cart' );

    if ( $this->populated ) {
        if ( in_array( $status, $allowed_statuses ) ) {
            wp_update_post( array( 'ID' => $this->id, 'post_status' => $status ) );

            // Reschedule cron
            $this->schedule_events();

            // Trigger actions
            do_action( 'woocommerce_booking_' . $current_status . '_to_' . $status, $this->id );
            do_action( 'woocommerce_booking_' . $status, $this->id );

            // Note in the order
            if ( $order = $this->get_order() ) {
                $order->add_order_note( sprintf( __( 'Booking #%d status changed from "%s" to "%s', 'woocommerce-bookings' ), $this->id, $current_status, $status ) );
            }

            return true;
        }
    }

    return false;
}

/**
 * Checks the booking status against a passed in status.
 *
 * @return bool
 */
public function has_status( $status ) {
    return apply_filters( 'woocommerce_booking_has_status', ( is_array( $status ) && in_array( $this->get_status(), $status ) ) || $this->get_status() === $status ? true : false, $this, $status );
}

/**
 * Returns the status of this booking
 * @param Bool to ask for pretty status name (if false)
 * @return String of the booking status
 */
public function get_status( $raw = true ) {
    if ( $this->populated ) {
        if ( $raw ) {
            return $this->status;
        } else {
            $status_object = get_post_status_object( $this->status );
            return $status_object->label;
        }
    }

    return false;
}

/**
 * Returns the id of this booking
 * @return Id of the booking or false if booking is not populated
 */
public function get_id() {
    if ( $this->populated ) {
        return $this->id;
    }

    return false;
}

/**
 * Get the product ID for the booking
 * @return int or false if booking is not populated
 */
public function get_product_id() {
    if ( $this->populated ) {
        return $this->product_id;
    }

    return false;
}

/**
 * Returns the object of the order corresponding to this booking
 * @return Product object or false if booking is not populated
 */
public function get_product() {
    if ( empty( $this->product ) ) {
        if ( $this->populated && $this->product_id ) {
            $this->product = get_product( $this->product_id );
        } else {
            return false;
        }
    }

    return $this->product;
}

/**
 * Returns the object of the order corresponding to this booking
 * @return Order object or false if booking is not populated
 */
public function get_order() {
    if ( empty( $this->order ) ) {
        if ( $this->populated && ! empty( $this->order_id ) && 'shop_order' === get_post_type( $this->order_id ) ) {
            $this->order = wc_get_order( $this->order_id );
        } else {
            return false;
        }
    }

    return $this->order;
}

/**
 * Returns the cancel URL for a booking
 *
 * @param string $redirect
 * @return string
 */
public function get_cancel_url( $redirect = '' ) {
    $cancel_page = get_permalink( wc_get_page_id( 'myaccount' ) );

    if ( ! $cancel_page ) {
        $cancel_page = home_url();
    }

    return apply_filters( 'bookings_cancel_booking_url', wp_nonce_url( add_query_arg( array( 'cancel_booking' => 'true', 'booking_id' => $this->id, 'redirect' => $redirect ), $cancel_page ), 'woocommerce-bookings-cancel_booking' ) );
}

/**
 * Return if all day event
 * @return boolean
 */
public function is_all_day() {
    if ( $this->populated ) {
        if ( $this->all_day ) {
            return true;
        } else {
            return false;
        }
    }
    return false;
}

/**
 * See if this booking is booked on said date
 * @return boolean
 */
public function is_booked_on_day( $block_start, $block_end ) {
    if ( $this->populated ) {
        $loop_date        = $this->start;
        $multiday_booking = date( 'Y-m-d', $this->start ) < date( 'Y-m-d', $this->end );

        if ( $multiday_booking ) {
            if ( date( 'YmdHi', $block_end ) > date( 'YmdHi', $this->start ) || date( 'YmdHi', $block_start ) < date( 'YmdHi', $this->end ) ) {
                return true;
            }
            return false;
        }

        while ( $loop_date <= $this->end ) {
            if ( date( 'Y-m-d', $loop_date ) === date( 'Y-m-d', $block_start ) ) {
                return true;
            }
            $loop_date = strtotime( "+1 day", $loop_date );
        }
    }
    return false;
}

/**
 * See if this booking can still be cancelled by the user or not
 * @return boolean
 */
public function passed_cancel_day() {
    $booking = $this->get_product();

    if ( $booking !== false ) {
        $cancel_limit      = $booking->wc_booking_cancel_limit;
        $cancel_limit_unit = $cancel_limit > 1 ? $booking->wc_booking_cancel_limit_unit . 's' : $booking->wc_booking_cancel_limit_unit;
        $cancel_string     = sprintf( 'now +%d %s', $cancel_limit, $cancel_limit_unit );

        if ( strtotime( $cancel_string ) >= $this->start ) {
            return true;
        }
    }

    return false;
}

/**
 * Returns booking start date
 * @return string Date formatted via date_i18n
 */
public function get_start_date( $date_format = null, $time_format = null ) {
    if ( $this->populated && ! empty( $this->start ) ) {
        if ( is_null( $date_format ) ) {
            $date_format = apply_filters( 'woocommerce_bookings_date_format', 'M jS Y' );
        }
        if ( is_null( $time_format ) ) {
            $time_format = apply_filters( 'woocommerce_bookings_time_format', ', g:ia' );
        }
        if ( $this->is_all_day() ) {
            return date_i18n( $date_format, $this->start );
        } else {
            return date_i18n( $date_format . $time_format, $this->start );
        }
    }

    return false;
}

/**
 * Returns booking end date
 * @return string Date formatted via date_i18n
 */
public function get_end_date( $date_format = null, $time_format = null ) {
    if ( $this->populated && ! empty( $this->end ) ) {
        if ( is_null( $date_format ) ) {
            $date_format = apply_filters( 'woocommerce_bookings_date_format', 'M jS Y' );
        }
        if ( is_null( $time_format ) ) {
            $time_format = apply_filters( 'woocommerce_bookings_time_format', ', g:ia' );
        }
        if ( $this->is_all_day() ) {
            return date_i18n( $date_format, $this->end );
        } else {
            return date_i18n( $date_format . $time_format, $this->end );
        }
    }

    return false;
}

/**
 * Returns information about the customer of this order
 * @return array containing customer information
 */
public function get_customer() {
    if ( $this->populated ) {
        $order = $this->get_order();

        if ( $order )
            return (object) array(
                'name'    => trim( $order->billing_first_name . ' ' . $order->billing_last_name ),
                'email'   => $order->billing_email,
                'user_id' => $order->customer_user,
            );
        elseif ( $this->customer_id ) {
            $user = get_user_by( 'id', $this->customer_id );

            return (object) array(
                'name'    => $user->display_name,
                'email'   => $user->user_email,
                'user_id' => $this->customer_id
            );
        }
    }

    return false;
}

/**
 * Returns if persons are enabled/needed for the booking product
 * @return boolean
 */
public function has_persons() {
    return $this->get_product()->has_persons();
}

/**
 * Returns if resources are enabled/needed for the booking product
 * @return boolean
 */
public function has_resources() {
    return $this->get_product()->has_resources();
}

/**
 * Return a array with the booking persons.
 * @return array
 */
public function get_persons() {
    return (array) $this->persons;
}

/**
 * Return the amount of persons for this booking.
 * @return int
 */
public function get_persons_total() {
    return array_sum( $this->get_persons() );
}

/**
 * Get the resource id
 * @return int
 */
public function get_resource_id() {
    if ( $this->populated ) {
        return absint( $this->resource_id );
    }
    return 0;
}

/**
 * Get the resource/type for this booking if applicable.
 * @return bool|object WP_Post
 */
public function get_resource() {
    $resource_id = $this->get_resource_id();

    if ( ! $resource_id || ! ( $product = $this->get_product() ) || ! method_exists( $product, 'get_resource' ) ) {
        return false;
    }

    return $product->get_resource( $resource_id );
}

}

和第57行

/**
 * Returns if persons are enabled/needed for the booking product
 * @return boolean
 */
public function has_persons() {
    return $this->get_product()->has_persons();
}

有人能帮助我吗?

谢谢

1 个答案:

答案 0 :(得分:2)

我使用此修复解决了完全相同的错误消息:

在文件夹中 的/ var / www / html等/可湿性粉剂内容/插件/ woocommerce-预订/包括

在档案中: 类-WC-booking.php

替换:

/**
 * Returns if persons are enabled/needed for the booking product

 * @return boolean

 */



public function has_persons() {
    return $this->get_product()->has_persons();
}

通过:

/**
 * Returns if persons are enabled/needed for the booking product

 * @return boolean

 */



public function has_persons() {
    if ($this->get_product()) {

    return $this->get_product()->has_persons();
        } else
        {
        return 0;
    }

}