פיצ׳ר ״עטיפה כמתנה״ הינו פיצ׳ר נחמד ושימושי מאוד, בעיקר בקרב חברות אשר מציעות מתנות לעובדים, או אתרים אשר מאפשרים לשלוח דברים לאנשים. לרוב בעלי חנויות לא ממשים את פיצ׳ר זה וזה חבל מכיוון שזה מסבך את ההתנהלות או אפילו גורם לנטישה של העגלה כאשר גולש מחפש לקנות מתנה עבור מישהו ואין אפשרות של עטיפה כמתנה.

שימו לב, במאמר זה אנו מכניסים את הקוד לקובץ function.php של התבנית, דבר זה פחות מומלץ מכיוון שזאת פונקציונליות שלא קשורה לתבנית. ניתן להוריד את הקוד בקובץ אשר מגדיר אותו כתוסף ולהתקין.

שלב ראשון – יצירת הגדרות תוסף

בשלב הראשון אנו נוסיף טאב חדש לממק עריכת מוצר אשר יאפשר לבעל החנות לבחור האם להפעיל עבור מוצר ספציפי את האפשרות לעטיפה כמתנה, ולבחור את עלות עטיפה כמתנה. מרבית הקוד בשלב זה מתבסס על קוד של מאמר שכתבנו בעבר – הגבלת כמות רכישה בווקומרס.

יצירת טאב חדש

/**
 * Add new tab to woocommerce product editing screen.
 *
 * @param array $tabs list of tabs and configuration.
 *
 * @return array
 */
function dorzki_add_gift_wrap_tab( $tabs ) {

	$tabs['product_gift_wrap'] = [
		'label'  => __( 'Gift Wrap', 'dorzki-wc-gift-wrap' ),
		'target' => 'gift_wrap_options',
		'class'  => 'show_if_simple',
	];

	return $tabs;

}

add_filter( 'woocommerce_product_data_tabs', 'dorzki_add_gift_wrap_tab' );

בשלב זה אנו משתמשים בהוק של ווקומרס woocommerce_product_data_tabs על מנת להוסיף טאב חדש אשר יהיה מוצג רק במוצרים רגילים, ויכיל בהמשך את שדות ההגדרות של התוסף.

יצירת שדות של הגדרות התוסף

/**
 * Print gift wrap panel fields.
 */
function dorzki_gift_wrap_options_panel() {

	echo "<div id='gift_wrap_options' class='panel woocommerce_options_panel'>";
	echo "	<div class='options_group'>";

	woocommerce_wp_checkbox( [
		'id'          => '_gift_wrap_enabled',
		'label'       => __( 'Enable Gift Wrap', 'dorzki-wc-gift-wrap' ),
		'desc_tip'    => 'true',
		'description' => __( 'Check in order to enable gift wrapping for this product.', 'dorzki-wc-gift-wrap' ),
	] );

	woocommerce_wp_text_input( [
		'id'                => '_gift_wrap_price',
		'label'             => __( 'Gift Wrap Fee', 'dorzki-wc-gift-wrap' ),
		'desc_tip'          => 'true',
		'description'       => __( 'Set service fee for this product ( 0 = Free ).', 'dorzki-wc-gift-wrap' ),
		'type'              => 'number',
		'custom_attributes' => [
			'min'  => 0,
			'step' => 0.1,
		],
	] );

	echo "	</div>";
	echo "</div>";

}

add_action( 'woocommerce_product_data_panels', 'dorzki_gift_wrap_options_panel' );

לאחר ישצרנו את הטאב, עלינו ליצור את השדות הרלוונטיים לתוסף שלנו על מנת שיוצגו בטאב, לכן נשמש בהוק woocommerce_product_data_panels ובפונקציות woocommerce_wp_checkbox ו-woocommerce_wp_text_input על מנת ליצור את השדות בפאנל של הטאב.

שמירת הגדרות המוצר

/**
 * Save gift wrap options panel fields data.
 *
 * @param int $product_id current product id.
 */
function dorzki_gift_wrap_save_options( $product_id ) {

	update_post_meta( $product_id, '_gift_wrap_enabled', $_POST['_gift_wrap_enabled'] );
	update_post_meta( $product_id, '_gift_wrap_price', $_POST['_gift_wrap_price'] );

}

add_action( 'woocommerce_process_product_meta_simple', 'dorzki_gift_wrap_save_options' );

כאשר מנהל החנות יערוך את המוצר עלינו לתפוס את המידע מהשדות שיצרנו ולשמור אותם במסד, לכן נשתמש בהוק woocommerce_process_product_meta_simple אשר רץ כאשר וורדפרס מבצעת שמירה של המידע בעמוד.

שלב שני – הצגת אפשרות לעטיפה בעמוד מוצר

בשלב זה לאחר שנתנו את האפשרות למנהל החנות להחליט עבור איזה מוצרים הוא מעוניין שתהיה האפשרות של עטיפה כמתנה, כעת עלינו להציג את האופציה בעמוד המוצר, ולטפל בכל התהליך של שמירת המידע וחישוב מחיר העטיפה בעגלה. מרבית הקוד בשלב זה מתבסס על קוד של מאמר שכתבתנו בעבר – הוספת שדות לעמוד מוצר ב-WooCommerce.

הצגת שדה עטיפה כמתנה בעמוד מוצר

/**
 * Display the gift wrap field on product page.
 */
function dorzki_print_gift_wrap_field() {

	global $product;

	if ( ! get_post_meta( $product->get_ID(), '_gift_wrap_enabled', true ) ) {
		return;
	}

	$price =  get_post_meta( $product->get_ID(), '_gift_wrap_price', true );
	$price = ( empty( $price ) ) ? __( 'FREE', 'dorzki-wc-gift-wrap' ) : wc_price( $price );

	$text = sprintf( __( 'Gift Wrap (%s)', 'dorzki-wc-gift-wrap' ), $price );

	echo "<div class='gift-wrap-wrapper'>";
	echo "	<label><input type='checkbox' id='wrap_as_gift' name='wrap_as_gift' value='1'>{$text}</label>";
	echo "</div>";

}

add_action( 'woocommerce_before_add_to_cart_quantity', 'dorzki_print_gift_wrap_field' );

על מנת להציג את השדה של הבחירה האם לעטוף כמתנה בעמוד מוצר נשתמש בהוק woocommerce_before_add_to_cart_quantity אשר ימקם את השדה שלנו מעל לכפתור הוספה לסל.

צילום מסך של עמוד מוצר עם שדה עטוף כמתנה

שמירת בחירת המשתמש

/**
 * Save the field value to current cart session.
 *
 * @param array $cart_item cart item data.
 *
 * @return array
 */
function dorzki_save_gift_wrap_field_value( $cart_item ) {

	$field_value = ( isset( $_POST[ 'wrap_as_gift' ] ) ) ? sanitize_text_field( $_POST[ 'wrap_as_gift' ] ) : null;

	if ( ! empty( $field_value ) ) {
		$cart_item[ 'wrap_as_gift' ] = $field_value;
	}

	return $cart_item;

}

add_filter( 'woocommerce_add_cart_item_data', 'dorzki_save_gift_wrap_field_value' );


/**
 * Stores cart item field data to current cart session.
 *
 * @param array $cart_item_data cart item data.
 * @param array $values         product item data.
 *
 * @return array
 */
function dorzki_save_gift_wrap_field_value_session( $cart_item_data, $values ) {

	if ( isset( $values[ 'wrap_as_gift' ] ) ) {
		$cart_item_data[ 'wrap_as_gift' ] = $values[ 'wrap_as_gift' ];
	}

	return $cart_item_data;

}

add_filter( 'woocommerce_get_cart_item_from_session', 'dorzki_save_gift_wrap_field_value_session', 10, 2 );

כאשר הגולש לוחץ על הוסף לסל, במידה והוא סימן שהוא מעוניין לעטוף את המוצר כמתנה, עלינו לשמור את הבחירה שלו ולשייך אותה למוצר הרלוונטי כדי שזה יוצג גם בעמוד הזמנה וגם בעגלה עצמה, לכן נשתמש בהוקים woocommerce_add_cart_item_data ו-woocommerce_get_cart_item_from_session.

שלב שלישי – הצגת בחירת המשתמש בעמוד עגלה

בשלב זה נדאג לטפל בכל מקרה שקשור להצגת בחירת המשתמש בעמוד עגלה ושינוי מחיר המוצר על מנת להציג את עלות השירות.

הוספת מחיר העטיפה למחיר המוצר

/**
 * Change product pricing to include gift wrap price.
 *
 * @param WC_Cart $cart woocommerce user cart.
 */
function dorzki_calculate_gift_wrap( $cart ) {

	if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
		return;
	}

	foreach ( $cart->get_cart() as $product_data ) {

		if ( isset( $product_data[ 'wrap_as_gift' ] ) ) {

			$price = get_post_meta( $product_data['data']->get_ID(), '_gift_wrap_price', true );

			if ( empty( $price ) ) {
				continue;
			}

			$product_data['data']->set_price( $product_data['data']->get_price() + $price );

		}

	}

}

add_action( 'woocommerce_before_calculate_totals', 'dorzki_calculate_gift_wrap' );

במידה והגולש בחר שהוא מעוניין בעטיפה של המוצר כמתנה, נרצה להוסיף את מחיר המתנה למחיר המוצר, לכן עלינו להתערב בתהליך חישוב העגלה על מנת שישקף גם את העלות של שירות עטיפה כמתנה. על מנת להתערב בתהליך חישוב העגלה, נשתמש בהוק woocommerce_before_calculate_totals ונעשה בדיקה האם המוצר הנוכחי כולל עטיפת מתנה, במידה וכן, נוסיף למחיר המוצר את מחיר השירות.

הצגת בחירת המשתמש בעמוד עגלה

/**
 * Display gift wrap if user selected on cart page.
 *
 * @param array $item_data item registered data.
 * @param array $cart_item item saved data.
 *
 * @return array
 */
function dorzki_display_gift_wrap_on_cart_page( $item_data, $cart_item ) {

	if ( ! empty( $cart_item[ 'wrap_as_gift' ] ) ) {

		$price = get_post_meta( $cart_item['data']->get_ID(), '_gift_wrap_price', true );
		$price = ( empty( $price ) ) ? __( 'FREE', 'dorzki-wc-gift-wrap' ) : wc_price( $price );

		$item_data[] = [
			'name'  => esc_html__( 'Gift Wrap', 'dorzki-wc-gift-wrap' ),
			'value' => sprintf( esc_html__( 'Yes (%s)', 'dorzki-wc-gift-wrap' ), $price ),
		];

	}

	return $item_data;

}

add_filter( 'woocommerce_get_item_data', 'dorzki_display_gift_wrap_on_cart_page', 10, 2 );

בעמוד עגלה נרצה להציג מתחת לכל מוצר שבחרנו לעטוף כמתנה את בחירה המשתמש, במידה והוא בחר לעטוף את המוצר כמתנה, נציג לו את מחיר השירות, במידה ולא, לא יוצג דבר.

שלב רביעי – הצגת בחירה המשתמש במסך הזמנה

בשלב הרביעי והאחרון נדאג לשמור את בחירה המשתמש כאשר הוא ביצע תשלום והצגת הנתונים בעמוד ההזמנה של מנהל החנות ובמסך סיכום ההזמנה של הגולש.

שמירת בחירת המשתמש בעת תשלום

/**
 * Saves the order data to database.
 *
 * @param int   $item_id order item id.
 * @param array $values  order item data.
 */
function dorzki_save_gift_wrap_order( $item_id, $values ) {

	if ( ! empty( $values[ 'wrap_as_gift' ] ) ) {
		wc_add_order_item_meta( $item_id, 'wrap_as_gift', $values[ 'wrap_as_gift' ] );
	}

}

add_action( 'woocommerce_add_order_item_meta', 'dorzki_save_gift_wrap_order', 10, 2 );

כאשר הגולש עובר לעמוד תשלום עלינו לשמור את הערך על מנת שנוכל להציג אותו במסך ההזמנה של האדמין ובסיכום ההזמנה של הגולש, לכן נשתמש בהוק woocommerce_add_order_item_meta ובפונקציה wc_add_order_item_meta לצורך משימה זו.

הצגת בחירת המשתמש בעמוד הזמנה

/**
 * Change the admin meta display key.
 *
 * @param string $display_key meta display key.
 *
 * @return string
 */
function dorzki_display_gift_wrap_order_key( $display_key ) {

	return ( 'wrap_as_gift' === $display_key ) ? __( 'Gift Wrap', 'dorzki-wc-gift-wrap' ) : $display_key;

}

add_action( 'woocommerce_order_item_display_meta_key', 'dorzki_display_gift_wrap_order_key' );


/**
 * Change the admin meta display value.
 *
 * @param mixed  $display_value meta display value.
 * @param object $meta          meta details.
 *
 * @return mixed
 */
function dorzki_display_gift_wrap_order_value( $display_value, $meta ) {

	if ( 'wrap_as_gift' === $meta->key ) {
		return __( 'Yes', 'dorzki-wc-gift-wrap' );
	}

	return $display_value;

}

		add_action( 'woocommerce_order_item_display_meta_value', 'dorzki_display_gift_wrap_order_value', 10, 2 );

לבסוף על מנת להציג את בחירת המשתמש במסך ההזמנה של האדמין ובסיכום ההזמנה של הגולש, נשתמש בהוקים woocommerce_order_item_display_meta_key ו-woocommerce_order_item_display_meta_value על מנת לשנות את הערכים ככה שהם יוצגו בצורה נעימה לעין.

סיכום

אפשרות לעטיפת מוצר כמתנה, הינו פיצ׳ר מאוד נחמד שיכול לתרום להרבה חנויות, עם הבנה של הקוד וטיפה שינויים ניתן לבצע עוד הרבה דברים אשר עובדים בצורה דומה ולהגיע לכל מיני תוצאות מגניבות.

    כתיבת תגובה

    1. קונדלה

      לא הבנתי…
      אני חייב לעשות עריכת קוד בקובץ function.php או שיש תוסף שניתן להוריד ולהתקין רגיל?

      הגב
      1. דור צוברי

        היי קונדלה,
        יש לך את האפשרות להעתיק את הקוד ולהדביק בקובץ functions.php או שאתה יכול פשוט להוריד את התוסף (דרך כפתור ״קבצי מקור״) ולהתקין דרך וורדפרס.

    2. מירי רובינשטיין

      היי דור
      תודה על המאמר עזר לי מאד
      הוספתי גם אופציה לברכה אישית
      אני לא מצליחה ב"הצגת בחירת המשתמש בעמוד הזמנה"
      להוסיף את המידע על הברכה כי זה מחזיר ערך אחד

      הגב
      1. דור צוברי

        היי מירי 🙂
        מה הכוונה מחזיר ערך אחד? את המספר ״1״? או מחזיר רק ערך אחד מבין כמה ערכים?

    3. מירי רובינשטיין

      תודה על תגובתך
      מחזיר לי רק ערך אחד מתוך שניים
      ואני צריכה שיחזיר לי גם את הערך שבחר באריזת מתנה וכן ערך נוסף שזה הברכה האישית

      הגב
      1. דור צוברי

        היי מירי,
        תוודאי שעשית את כל הצעדים, שימי לב שהצעדים מדברים על שדה אחד, אם את צריכה יותר משדה אחד וודאי שאת משנה את כל הקוד ככה שתהיה גם שמירה וגם שליפה והצגה של המידע.

    אפשר להציע לך עוגיות? יש גם קפה! השימוש בקוקיז עוזר לשפר את הביקור שלך באתר. המשך גלישה אומר שהסכמת למדיניות הפרטיות שלי, וגם לקפה.

    שתפו