id = 'offer_price'; $this->short_desc = __( 'Offer Your Price', 'woocommerce-jetpack' ); $this->desc = __( 'Let your customers to suggest their price for products.', 'woocommerce-jetpack' ); $this->link_slug = 'woocommerce-offer-your-product-price'; parent::__construct(); if ( $this->is_enabled() ) { if ( 'disable' != ( $_hook = get_option( 'wcj_offer_price_button_position', 'woocommerce_single_product_summary' ) ) ) { add_action( $_hook, array( $this, 'add_offer_price_button' ), get_option( 'wcj_offer_price_button_position_priority', 31 ) ); } if ( 'disable' != ( $_hook = apply_filters( 'booster_option', 'disable', get_option( 'wcj_offer_price_button_position_archives', 'disable' ) ) ) ) { add_action( $_hook, array( $this, 'add_offer_price_button' ), get_option( 'wcj_offer_price_button_position_priority_archives', 10 ) ); } add_action( 'woocommerce_before_main_content', array( $this, 'add_offer_price_form' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); add_action( 'init', array( $this, 'offer_price' ) ); if ( 'per_product' === apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) ) { add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) ); add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 ); } // Offer history add_action( 'add_meta_boxes', array( $this, 'add_offer_price_history_meta_box' ) ); add_action( 'save_post_product', array( $this, 'delete_offer_price_product_history' ), PHP_INT_MAX, 2 ); // CSS add_action( 'wp_head', array( $this, 'add_styling' ), PHP_INT_MAX ); } } /** * add_styling. * * @version 3.7.0 * @since 3.7.0 */ function add_styling() { $styling_default = array( 'form_content_width' => '80%', 'form_header_back_color' => '#5cb85c', 'form_header_text_color' => '#ffffff', 'form_footer_back_color' => '#5cb85c', 'form_footer_text_color' => '#ffffff', ); $styling_options = get_option( 'wcj_offer_price_styling', array() ); foreach ( $styling_default as $option => $default ) { if ( ! isset( $styling_options[ $option ] ) ) { $styling_options[ $option ] = $default; } } echo ""; } /** * delete_offer_price_product_history. * * @version 2.9.0 * @since 2.9.0 * @todo (maybe) add successful deletion notice */ function delete_offer_price_product_history( $post_id, $post ) { if ( isset( $_POST['wcj_offer_price_delete_history'] ) ) { delete_post_meta( $post_id, '_' . 'wcj_price_offers' ); add_action( 'admin_notices', array( $this, 'notice_delete_offer_price_product_history' ) ); } } /** * add_offer_price_history_meta_box. * * @version 2.9.0 * @since 2.9.0 */ function add_offer_price_history_meta_box() { add_meta_box( 'wc-booster-offer-price-history', __( 'Booster: Offer Price History', 'woocommerce-jetpack' ), array( $this, 'create_offer_price_history_meta_box' ), 'product', 'normal', 'high' ); } /** * create_offer_price_history_meta_box. * * @version 2.9.0 * @since 2.9.0 */ function create_offer_price_history_meta_box() { if ( '' == ( $price_offers = get_post_meta( get_the_ID(), '_' . 'wcj_price_offers', true ) ) ) { echo '' . __( 'No price offers yet.', 'woocommerce-jetpack' ) . ''; } else { $average_offers = array(); $table_data = array(); $table_data[] = array( __( 'Date', 'woocommerce-jetpack' ), __( 'Price', 'woocommerce-jetpack' ), __( 'Message', 'woocommerce-jetpack' ), __( 'Name', 'woocommerce-jetpack' ), __( 'Email', 'woocommerce-jetpack' ), __( 'Customer ID', 'woocommerce-jetpack' ), __( 'Sent to', 'woocommerce-jetpack' ), ); $date_ant_time_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' ); $price_offers = array_reverse( $price_offers ); foreach ( $price_offers as $price_offer ) { $table_data[] = array( date_i18n( $date_ant_time_format, $price_offer['offer_timestamp'] ), wc_price( $price_offer['offered_price'], array( 'currency' => $price_offer['currency_code'] ) ), $price_offer['customer_message'], $price_offer['customer_name'], $price_offer['customer_email'], $price_offer['customer_id'], $price_offer['sent_to'] . ( 'yes' === $price_offer['copy_to_customer'] ? '
' . $price_offer['customer_email'] : '' ), ); if ( ! isset( $average_offers[ $price_offer['currency_code'] ] ) ) { $average_offers[ $price_offer['currency_code'] ] = array( 'total_offers' => 0, 'offers_sum' => 0 ); } $average_offers[ $price_offer['currency_code'] ]['total_offers']++; $average_offers[ $price_offer['currency_code'] ]['offers_sum'] += $price_offer['offered_price']; } echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) ); foreach ( $average_offers as $average_offer_currency_code => $average_offer_data ) { echo '

' . sprintf( __( 'Average offer: %s (from %s offer(s))', 'woocommerce-jetpack' ), wc_price( ( $average_offer_data['offers_sum'] / $average_offer_data['total_offers'] ), array( 'currency' => $average_offer_currency_code ) ), $average_offer_data['total_offers'] ) . '

'; } echo '

' . '' . '' . wc_help_tip( __( 'Update product after checking the box.', 'woocommerce-jetpack' ) ) . '

'; } } /** * enqueue_scripts. * * @version 2.9.0 * @since 2.9.0 * @see https://www.w3schools.com/howto/howto_css_modals.asp * @todo (maybe) enqueue only if really needed */ function enqueue_scripts() { wp_enqueue_style( 'wcj-offer-price', wcj_plugin_url() . '/includes/css/wcj-offer-price.css', array(), WCJ()->version ); wp_enqueue_script( 'wcj-offer-price-js', wcj_plugin_url() . '/includes/js/wcj-offer-price.js', array( 'jquery' ), WCJ()->version, true ); } /** * is_offer_price_enabled_for_product. * * @version 3.7.0 * @since 2.9.0 */ function is_offer_price_enabled_for_product( $product_id ) { switch ( apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) ) { case 'all_products': return true; case 'empty_prices': $_product = wc_get_product( $product_id ); return ( '' === $_product->get_price() ); case 'per_product': return ( 'yes' === get_post_meta( $product_id, '_' . 'wcj_offer_price_enabled', true ) ); case 'per_category': return wcj_is_product_term( $product_id, get_option( 'wcj_offer_price_enabled_cats', array() ), 'product_cat' ); } } /** * get_wcj_data_array. * * @version 2.9.0 * @since 2.9.0 * @todo (maybe) rethink `str_replace( '\'', '"', ... )` */ function get_wcj_data_array( $product_id ) { $is_per_product_enabled = ( 'per_product' === apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) ); // Price input - price step $price_step = ( ! $is_per_product_enabled || '' === ( $price_step_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_price_step', true ) ) ? get_option( 'wcj_offer_price_price_step', get_option( 'woocommerce_price_num_decimals' ) ) : $price_step_per_product ); $price_step = sprintf( "%f", ( 1 / pow( 10, absint( $price_step ) ) ) ); // Price input - min price $min_price = ( ! $is_per_product_enabled || '' === ( $min_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_min_price', true ) ) ? get_option( 'wcj_offer_price_min_price', 0 ) : $min_price_per_product ); // Price input - max price $max_price = ( ! $is_per_product_enabled || '' === ( $max_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_max_price', true ) ) ? get_option( 'wcj_offer_price_max_price', 0 ) : $max_price_per_product ); // Price input - default price $default_price = ( ! $is_per_product_enabled || '' === ( $default_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_default_price', true ) ) ? get_option( 'wcj_offer_price_default_price', 0 ) : $default_price_per_product ); // Price input - label $price_label = str_replace( '%currency_symbol%', get_woocommerce_currency_symbol(), get_option( 'wcj_offer_price_price_label', sprintf( __( 'Your price (%s)', 'woocommerce-jetpack' ), '%currency_symbol%' ) ) ); // Offer form - header $form_header = str_replace( '%product_title%', get_the_title(), get_option( 'wcj_offer_price_form_header_template', '

' . sprintf( __( 'Suggest your price for %s', 'woocommerce-jetpack' ), '%product_title%' ) . '

' ) ); return array( 'price_step' => $price_step, 'min_price' => $min_price, 'max_price' => $max_price, 'default_price' => $default_price, 'price_label' => str_replace( '\'', '"', $price_label ), 'form_header' => str_replace( '\'', '"', $form_header ), 'product_id' => $product_id, ); } /** * add_offer_price_form. * * @version 2.9.0 * @since 2.9.0 * @todo (maybe) fix when empty header * @todo (maybe) style options for input fields (class, style) * @todo (maybe) form template * @todo (maybe) do_shortcode in form header and footer * @todo (maybe) logged user - check `nickname` and `billing_email` * @todo (maybe) better required asterix default * @todo (maybe) optional, additional and custom form fields */ function add_offer_price_form() { // Prepare logged user data $customer_name = ''; $customer_email = ''; $customer_id = 0; if ( is_user_logged_in() ) { $current_user = wp_get_current_user(); $customer_id = $current_user->ID; if ( '' != ( $meta = get_user_meta( $current_user->ID, 'nickname', true ) ) ) { $customer_name = $meta; } if ( '' != ( $meta = get_user_meta( $current_user->ID, 'billing_email', true ) ) ) { $customer_email = $meta; } } // Header $offer_form_header = '
' . '×' . '
' . '
'; // Footer $offer_form_footer = ( '' != ( $footer_template = get_option( 'wcj_offer_price_form_footer_template', '' ) ) ? '' : '' ); // Required HTML $required_html = get_option( 'wcj_offer_price_form_required_html', ' *' ); // Content - price $offer_form_content_price = '' . '
' . ''; // Content - email $offer_form_content_email = '' . '
' . ''; // Content - name $offer_form_content_name = '' . '
' . ''; // Content - message $offer_form_content_message = '' . '
' . ''; // Content - button $offer_form_content_button = ''; // Content - copy $offer_form_content_copy = '' . ' ' . ''; // Content $offer_form_content = '
' . '
' . '

' . $offer_form_content_price . '

' . '

' . $offer_form_content_email . '

' . '

' . $offer_form_content_name . '

' . '

' . $offer_form_content_message . '

' . '

' . $offer_form_content_button . '

' . '

' . $offer_form_content_copy . '

' . '' . '' . '
' . '
'; // Final form echo '
' . '
' . $offer_form_header . $offer_form_content . $offer_form_footer . '
' . '
'; } /** * add_offer_price_button. * * @version 3.0.0 * @since 2.9.0 */ function add_offer_price_button() { $product_id = get_the_ID(); // Check if enabled for current product if ( ! $this->is_offer_price_enabled_for_product( $product_id ) ) { return; } // The button if ( '' != $additional_class = get_option( 'wcj_offer_price_button_class', 'button' ) ) { $additional_class = ' ' . $additional_class; } echo '

' . '' . '

'; } /** * offer_price. * * @version 2.9.0 * @since 2.9.0 * @todo (maybe) separate customer copy email template and subject * @todo (maybe) redirect (no notice though) * @todo (maybe) `%product_title%` etc. in notice * @todo (maybe) fix "From" header * @todo (maybe) check if mail has really been sent * @todo (maybe) sanitize $_POST */ function offer_price() { if ( isset( $_POST['wcj-offer-price-submit'] ) ) { $product_id = $_POST['wcj-offer-price-product-id']; $_product = wc_get_product( $product_id ); // Email address $email_address = get_option( 'wcj_offer_price_email_address', '%admin_email%' ); if ( '' == $email_address ) { $email_address = get_option( 'admin_email' ); } else { $admin_email = get_option( 'admin_email' ); if ( ( $product_author_id = get_post_field( 'post_author', $product_id ) ) && ( $product_user_info = get_userdata( $product_author_id ) ) && isset( $product_user_info->user_email ) ) { $product_author_email = $product_user_info->user_email; } else { $product_author_email = $admin_email; } $email_address = str_replace( array( '%admin_email%', '%product_author_email%' ), array( $admin_email, $product_author_email ), $email_address ); } // Price offer array $price_offer = array( 'offer_timestamp' => current_time( 'timestamp' ), 'product_title' => $_product->get_title(), 'offered_price' => $_POST['wcj-offer-price-price'], 'currency_code' => get_woocommerce_currency(), 'customer_message' => $_POST['wcj-offer-price-message'], 'customer_name' => $_POST['wcj-offer-price-customer-name'], 'customer_email' => $_POST['wcj-offer-price-customer-email'], 'customer_id' => $_POST['wcj-offer-price-customer-id'], 'copy_to_customer' => ( isset( $_POST['wcj-offer-price-customer-copy'] ) ? $_POST['wcj-offer-price-customer-copy'] : 'no' ), 'sent_to' => $email_address, ); // Email content $email_template = get_option( 'wcj_offer_price_email_template', sprintf( __( 'Product: %s', 'woocommerce-jetpack' ), '%product_title%' ) . '
' . PHP_EOL . sprintf( __( 'Offered price: %s', 'woocommerce-jetpack' ), '%offered_price%' ) . '
' . PHP_EOL . sprintf( __( 'From: %s %s', 'woocommerce-jetpack' ), '%customer_name%', '%customer_email%' ) . '
' . PHP_EOL . sprintf( __( 'Message: %s', 'woocommerce-jetpack' ), '%customer_message%' ) ); $replaced_values = array( '%product_title%' => $price_offer['product_title'], '%offered_price%' => wc_price( $price_offer['offered_price'] ), '%customer_message%' => $price_offer['customer_message'], '%customer_name%' => $price_offer['customer_name'], '%customer_email%' => $price_offer['customer_email'], ); $email_content = str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), $email_template ); // Email subject and headers $email_subject = get_option( 'wcj_offer_price_email_subject', __( 'Price Offer', 'woocommerce-jetpack' ) ); $email_headers = 'Content-Type: text/html' . "\r\n" . 'From: ' . $price_offer['customer_name'] . ' <' . $price_offer['customer_email'] . '>' . "\r\n" . 'Reply-To: ' . $price_offer['customer_email'] . "\r\n"; // Send email wc_mail( $email_address, $email_subject, $email_content, $email_headers ); if ( 'yes' === $price_offer['copy_to_customer'] ) { wc_mail( $price_offer['customer_email'], $email_subject, $email_content, $email_headers ); } // Notice wc_add_notice( get_option( 'wcj_offer_price_customer_notice', __( 'Your price offer has been sent.', 'woocommerce-jetpack' ) ), 'notice' ); // Product meta (Offer Price History) if ( '' == ( $price_offers = get_post_meta( $product_id, '_' . 'wcj_price_offers', true ) ) ) { $price_offers = array(); } $price_offers[] = $price_offer; update_post_meta( $product_id, '_' . 'wcj_price_offers', $price_offers ); } } } endif; return new WCJ_Offer_Price();