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

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

צעד ראשון – תבנית או תוסף?

הצעד הראשון הוא להחליט אם אתם מעוניינים להכניס את הקוד שיוצג במאמר לקובץ functions.php או לעטוף את כל הקוד כתוסף ולהתקין אותו באתר.

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

צעד שני – הוספת השדה לעמוד מוצר

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

/**
 * Inject the field just above the add to cart button.
 */
function dorzki_add_custom_product_field() {

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

	printf( '<label for="%1$s">%2$s</label><input type="text" id="%1$s" name="%1$s" value="%3$s">', 'dorzki_your_name', esc_html__( 'Your Name:', 'dorzki-wc-product-custom-field' ), $field_value );

}

add_action( 'woocommerce_before_add_to_cart_button', 'dorzki_add_custom_product_field' );

צעד שלישי – וולידציית ערך השדה שנשלח

בשלב הבא, אנו נרצה לבדוק האם השדה מולא, נעשה זאת ע״י שימוש במנגנון הוולידציה המובנה של WooCommerce.

/**
 * Check if user have entered data into the field.
 *
 * @param bool $passed     if product passed validation.
 * @param int  $product_id product id.
 *
 * @return bool
 */
public function dorzki_validate_submitted_field( $passed, $product_id ) {

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

	if ( empty( $field_value ) ) {

		$product = wc_get_product( $product_id );

		wc_add_notice( sprintf(
		/* translators: 1: Product Name */
			esc_html__( '"%1$s" can\'t be added to cart until you fill all data.', 'dorzki-wc-product-custom-field' ),
			"<strong>{$product->get_title()}</strong>"
		) );

		return false;

	}

	return $passed;

}

add_filter( 'woocommerce_add_to_cart_validation', 'dorzki_validate_submitted_field', 10, 2 );

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

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

צעד רביעי – שמירת הערך שנשלח

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

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

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

	if ( ! empty( $field_value ) ) {

		$cart_item[ 'dorzki_your_name' ] = $field_value;

	}

	return $cart_item;

}

add_filter( 'woocommerce_add_cart_item_data', 'dorzki_save_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
 */
public function dorzki_store_field_value_to_session( $cart_item_data, $values ) {

	if ( isset( $values[ 'dorzki_your_name' ] ) ) {

		$cart_item_data[ 'dorzki_your_name' ] = $values[ 'dorzki_your_name' ];

	}

	return $cart_item_data;

}

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

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

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

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

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

/**
 * Display custom field data on cart page.
 *
 * @param array $item_data item registered data.
 * @param array $cart_item item saved data.
 *
 * @return array
 */
public function dorzki_show_field_value_in_cart( $item_data, $cart_item ) {

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

		$item_data[] = [
			'name'  => esc_html__( 'Your Name', 'dorzki-wc-product-custom-field' ),
			'value' => sanitize_text_field( $cart_item[ 'dorzki_your_name' ] ),
		];

	}

	return $item_data;

}

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

ע״י שימוש הקוד הנ״ל, תחת שם המוצר יוצג לנו שם השדה והערך שהוכנס ע״י הרוכש.

צעד שישי – שמירת הערך לאחר תשלום

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

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

	if ( ! empty( $values[ 'dorzki_your_name' ] ) ) {

		wc_add_order_item_meta( $item_id, 'dorzki_your_name', $values[ 'dorzki_your_name' ] );

	}

}

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

צעד שביעי – הצגת הערך בעמוד אישור הזמנה

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

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

	return ( 'dorzki_your_name' === $display_key ) ? __( 'Your Name', 'dorzki-wc-product-custom-field' ) : $display_key;

}

add_filter( 'woocommerce_order_item_display_meta_key', 'dorzki_change_custom_field_name' );

הקוד הנ״ל משנה את הטקסט אשר מוצג לגולש ולאדמין, במקום שהוא יציג את מזהה השדה, הוא יציג את שם השדה.

צעד שמיני – הצגת הערך במייל שנשלח (אופציונלי)

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

/**
 * Display custom field data on email.
 *
 * @param array $fields array of fields.
 *
 * @return array
 */
public function dorzki_show_on_email( $fields ) {

	$fields[ self::$field_id ] = __( 'Your Name', 'dorzki-wc-product-custom-field' );

	return $fields;

}

add_filter( 'woocommerce_email_order_meta_fields', 'dorzki_show_on_email' );

סיכום להורדת הקוד המלא

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

    כתיבת תגובה

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

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

    2. מירי

      היי דור
      תודה
      היתה לנו משימת כיתה
      והשתמשנו קומפלט בקוד…….

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

        היי מירי,
        מגניב שמח לשמוע, באיזה מטלת כיתה זה היה?

    3. מירי

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

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

        שמח לשמוע! 🙂

    4. רונית

      היי דור,
      נעזרתי במאמר שלך.

      אך הפונקציה:
      'woocommerce_before_add_to_cart_button'
      הוספתי טאב שבחלק מהמקומות מופיע לי בשורה מעל ההוסף לסל (וזה מה שאני רוצה בעצם)
      אך בחלק מקומות מופיעה לי בשורה של ההוסף לסל ובשורה של הכמות של המוצר זה גורם לכל התוכן שהוספתי להיות מאוד מאוד צר בגלל זה.

      מה יכולה להיות הבעיה ואיך להתגבר על זה?

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

        היי רונית,
        הכל תלוי איך התבנית שלך בנויה.

        שימי לב שהקוד שלך תקין ושכל תגיות ה-HTML נסגרות לפי הסדר.
        בנוסף, תסתכלי על הקוד CSS של התבנית, ייתכן ובעמודים שונים (נגיד עמו מוצר רגיל, ועמוד מוצר עם וריאציות) המבנה שונה.

    5. רונית

      היי דור,
      תודה על העזרה.

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

      עדיין לא מצאתי רעיון איך להתגבר על זה. יש לך כוון בשבילי?

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

        היי רונית,
        אני מניח שזה משהו שתוכלי לפתור עם CSS.

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

    שתפו