' . esc_html( $message ) . '
';
}
}
/**
* Check HPOS feature enabled.
* WC declared HPOS (Hight Performance Order Storage) feature stable on october 2023 from WC v8.2
*
* @see https://woo.com/document/high-performance-order-storage
*
* @since 2.6.0
*
* @return bool
*/
public static function hpos_enabled() {
$hpos = false;
if ( tutor_utils()->has_wc() && version_compare( WC()->version, '8.2.0', '>=' ) ) {
$hpos = 'yes' === get_option( 'woocommerce_custom_orders_table_enabled' );
}
return $hpos;
}
/**
* Declare tutor compatibility with WC HPOS feature
*
* @since 2.6.0
*
* @return void
*/
public function declare_tutor_compatibility_with_hpos() {
if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', TUTOR_FILE, true );
}
}
/**
* On WC product delete, clear course linked product
*
* @since 2.0.7
*
* @param int $post_id post id.
*
* @return void
*/
public function clear_course_linked_product( $post_id ) {
if ( get_post_type( $post_id ) === 'product' ) {
global $wpdb;
$wpdb->query(
$wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_key=%s AND meta_value=%d", '_tutor_course_product_id', $post_id )
);
}
}
/**
* Order item callback handler
*
* @since 1.0.0
*
* @param string $product_permalink permalink.
* @param mixed $item order item.
* @param mixed $order orders.
*
* @return string permalink of course
*/
public function filter_order_item_permalink_callback( $product_permalink, $item, $order ) {
// For product variations.
if ( $item->get_variation_id() > 0 ) {
$product = $item->get_product();
$is_visible = $product && $product->is_visible();
// Get the instance of the parent variable product Object.
$parent_product = wc_get_product( $item->get_product_id() );
// Return the parent product permalink (if product is visible).
return $is_visible ? $parent_product->get_permalink() : '';
}
$course_id = $this->get_post_id_by_meta_key_and_value( '_tutor_course_product_id', $item->get_product_id() );
return get_permalink( $course_id );
}
/**
* Get post id my meta key & value
*
* @since 1.0.0
*
* @param mixed $key meta key.
* @param mixed $value meta value.
*
* @return mixed post id on success, false on failure
*/
public function get_post_id_by_meta_key_and_value( $key, $value ) {
global $wpdb;
$meta = $wpdb->get_results( 'SELECT * FROM `' . $wpdb->postmeta . "` WHERE meta_key='" . esc_sql( $key ) . "' AND meta_value='" . esc_sql( $value ) . "'" );
if ( is_array( $meta ) && ! empty( $meta ) && isset( $meta[0] ) ) {
$meta = $meta[0];
}
if ( is_object( $meta ) ) {
return $meta->post_id;
} else {
return false;
}
}
/**
* Check if course is purchase able
*
* @since 1.0.0
*
* @param bool $bool default value.
* @param int $course_id course id.
*
* @return boolean
*/
public function is_course_purchasable( $bool, $course_id ) {
if ( ! tutor_utils()->has_wc() ) {
return false;
}
$course_id = tutor_utils()->get_post_id( $course_id );
$price_type = tutor_utils()->price_type( $course_id );
$has_product_id = tutor_utils()->get_course_product_id( $course_id );
/**
* WC course bundle don't have free or paid price types.
* Check if the bundle has a WC product attached.
*/
if ( $has_product_id && tutor()->bundle_post_type === get_post_type( $course_id ) ) {
return true;
}
if ( Course::PRICE_TYPE_PAID === $price_type && $has_product_id ) {
return true;
}
return false;
}
/**
* Get course price
*
* @since 1.0.0
*
* @param mixed $price course price.
* @param int $course_id course id.
*
* @return string
*/
public function get_tutor_course_price( $price, $course_id ) {
$price = null;
if ( tutor_utils()->is_course_purchasable( $course_id ) ) {
if ( tutor_utils()->has_wc() ) {
$product_id = tutor_utils()->get_course_product_id( $course_id );
$product = wc_get_product( $product_id );
if ( $product ) {
ob_start();
?>