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

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

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

שלב ראשון – הוספת טאב חדש לממשק העריכה

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

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

	$tabs[ 'product_min_max' ] = [
		'label' => __( 'הגבלת כמות רכישה', 'dorzki' ),
		'target' => 'min_max_options',
		'class' => [ 'show_if_simple' ],
	];

	return $tabs;

}

add_filter( 'woocommerce_product_data_tabs', 'dorzki_add_min_max_limit_tab' );

הקוד הבא מזריק לרשימת הטאבים טאב חדש אשר יהיה נגיש אך ורק אם המוצר הוא מסוג מוצר רגיל (Simple).

שלב שני – הוספת שדות לטאב החדש

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

/**
 * Register the new minimum maximum fields and display them on the new tab.
 */
function dorzki_register_min_max_limit_fields() {

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

	woocommerce_wp_text_input( [
		'id' => '_min_quantity',
		'label'	 => __( 'מינימום כמות', 'dorzki' ),
		'desc_tip' => 'true',
		'description'	=> __( 'מינימום כמות לרכישה, יש להגדיר את המספר או 1 על מנת לבטל את מגבלת הרכישה.', 'dorzki' ),
		'type' => 'number',
		'custom_attributes'	=> [
			'min'	=> 1,
			'step' => 1,
		],
	] );

	woocommerce_wp_text_input( [
		'id' => '_max_quantity',
		'label'	 => __( 'מקסימום כמות', 'dorzki' ),
		'desc_tip' => 'true',
		'description'	=> __( 'מקסימום כמות לרכישה, יש להגדיר את המספר הרצוי או 0 על מנת לבטל את מגבלת הרכישה.', 'dorzki' ),
		'type' => 'number',
		'custom_attributes'	=> [
			'min'	=> 0,
			'step' => 1,
		],
	] );

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

}

add_action( 'woocommerce_product_data_panels', 'dorzki_register_min_max_limit_fields' );

בקטע קוד זה אנו מדפיסים את השדות החדשים באמלנט עוטף שהמזהה שלו (ID), זהה למזהה שרשמנו בסעיף הקודם ב-target.

צילום מסך המראה את הטאב החדש שיצרנו יחד עם השדות

שלב שלישי – שמירת נתונים במסד

כעת עלינו להגדיר לווקומרס לשמור את הערכים אשר יוכנסו בשדות אלו, על מנת לעשות זאת נשתמש ב-Hook המובנה של ווקומרס אשר נקרא woocommerce_process_product_meta_simple באופן הבא:

/**
 * Save the minimum maximum values to the database.
 *
 * @param int $product_id current product id.
 */
function dorzki_save_min_max_values( $product_id ) {

	update_post_meta( $product_id, '_min_quantity', $_POST[ '_min_quantity' ] );
	update_post_meta( $product_id, '_max_quantity', $_POST[ '_max_quantity' ] );

}

add_action( 'woocommerce_process_product_meta_simple', 'dorzki_save_min_max_values' );

אנו משתמשים בפונקציית update_post_meta של וורדפרס על מנת לשמור את הערכם האלו בטבלת postmeta עם שיוך למוצר הרלוונטי.

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

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

/**
 * Set product minimum quantity limit.
 *
 * @param int	     $min     minimum product quantity.
 * @param WP_Product $product current product object.
 *
 * @return int
 */
function dorzki_set_minimum_quantity_limit( $min, $product ) {

	$min_qty = get_post_meta( $product->get_ID(), '_min_quantity', true );

	if( $min_qty ) {

		$min = (int) $min_qty;

	}

	return $min;

}

add_filter( 'woocommerce_quantity_input_min', 'dorzki_set_minimum_quantity_limit', 10, 2 );


/**
 * Set product maximum quantity limit.
 *
 * @param int	     $max     maximum product quantity.
 * @param WP_Product $product current product object.
 *
 * @return int
 */
function dorzki_set_maximum_quantity_limit( $max, $product ) {

	$max_qty = get_post_meta( $product->get_ID(), '_max_quantity', true );

	if( $max_qty ) {

		$max = (int) $max_qty;

	}

	return $max;

}

add_filter( 'woocommerce_quantity_input_max', 'dorzki_set_maximum_quantity_limit', 10, 2 );

בקוד הבא אנו בודקים האם הוגדר הגבלת מינימום רכישה ו/או מקסימום רכישה, ולפי זה אנו משנים את ההגדרה של ערכי המינימום והמקסימום של שדה הכמות (Quantity) בעמוד המוצר.

שלב חמישי – בדיקת חוקיות לפני הוספה לסל

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

/**
 * Check if trying to add more or less then configured.
 *
 * @param bool $passed     passed validation?
 * @param int  $product_id product id number.
 * @param int  $quantity   amount added.
 *
 * @return bool
 */
function dorzki_check_min_max_limit( $passed, $product_id, $quantity ) {

	$product = wc_get_product( $product_id );

	if( $product->is_type( 'simple' ) ) {

		$min = get_post_meta( $product_id, '_min_quantity', true );
		$max = get_post_meta( $product_id, '_max_quantity', true );

		if( $quantity < $min ) {

			$passed = false;

			wc_add_notice( sprintf( __( 'ניתן לרכוש מינימום %s יחידות ממוצר זה.', 'dorzki' ), "<strong>{$min}</strong>" ), 'error' );

		} elseif( ! empty( $max ) && $quantity > $max ) {

			$passed = false;

			wc_add_notice( sprintf( __( 'ניתן לרכוש מקסימום %s יחידות ממוצר זה.', 'dorzki' ), "<strong>{$max}</strong>" ), 'error' );

		}

	}

	return $passed;

}

add_filter( 'woocommerce_add_to_cart_validation', 'dorzki_check_min_max_limit', 10, 3 );

במידה והגולש יכנס להכניס יותר מהמותר או פחות מהמותר, תוצג לו שגיאה (ע״י שימוש בפונקציה wc_add_notice) והמוצר לא יתווסך לסל.

שלב שישי – הפעלת חוקיות בעמוד עגלה

על מנת שהגבלת הרכישה תהיה גם בעגלה עצמה, נצטרך להוסיף עוד קצת קוד על מנת להגביל את שדה כמות (Quantity) בעמוד העגלה, לצורך כך נדביק את הקוד הבא:

/**
 * Add quantity filed minimum and maximum values according to configuration.
 *
 * @param array      $args    quantity field arguments.
 * @param WC_Product $product current product object.
 *
 * @return array
 */
function dorzki_set_min_max_values_in_cart( $args, $product ) {

	if( $product->is_type( 'simple' ) ) {

		$min = get_post_meta( $product->get_ID(), '_min_quantity', true );
		$max = get_post_meta( $product->get_ID(), '_max_quantity', true );

		$args['min_value'] = $min;
		$args['max_value'] = ( ! empty( $max ) ) ? $max : $args['max_value'];

	}

	return $args;

}

add_filter( 'woocommerce_quantity_input_args', 'dorzki_set_min_max_values_in_cart', 10, 2 );

שלב שביעי – בדיקת חוקיות לפני עדכון עגלה

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

/**
 * Check if trying to add more or less then configured on cart page.
 *
 * @param bool   $passed        passed validation?
 * @param string $cart_item_key cart item has id.
 * @param array  $cart_item     cart id data.
 * @param int    $quantity      product quantity.
 *
 * @return bool
 */
function dorzki_check_cart_min_max_limit( $passed, $cart_item_key, $cart_item, $quantity ) {

	if( $cart_item['data']->is_type( 'simple' ) ) {

		$min = get_post_meta( $cart_item['data']->get_ID(), '_min_quantity', true );
		$max = get_post_meta( $cart_item['data']->get_ID(), '_max_quantity', true );

		if( $quantity < $min ) {

			$passed = false;

			wc_add_notice( sprintf( __( 'ניתן לרכוש מינימום %s יחידות ממוצר זה.', 'dorzki' ), "<strong>{$min}</strong>" ), 'error' );

		} elseif( ! empty( $max ) && $quantity > $max ) {

			$passed = false;

			wc_add_notice( sprintf( __( 'ניתן לרכוש מקסימום %s יחידות ממוצר זה.', 'dorzki' ), "<strong>{$max}</strong>" ), 'error' );

		}

	}

	if( ! $passed ) {
		add_filter( 'woocommerce_update_cart_action_cart_updated', '__return_false' );
	}

	return $passed;

}

add_filter( 'woocommerce_update_cart_validation', 'dorzki_check_cart_min_max_limit', 10, 4 );

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

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

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

    כתיבת תגובה

    1. גיא יצחק

      כל הכבוד על ההשקעה. קצת וקולע.

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

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

        היי גיא,
        תודה רבה אחי, שמח לשמוע 🙂

        ותתפלא, יש דרישות לפעמים שאני מקבל מלקוחות שאני אומר לעצמי, זה מוזר, אבל מה שהלקוח רוצה, הוא מקבל 🙂

    2. איציק

      מדהים!!!
      אשמח לדעת איך לשנות גם את הקפיצות של מעל המינימום…
      כלומר אם אני מוכר לצורך העניין תריסר ביצים…אז המינימום שלי הוא 12 אבל אני לא רוצה שיזמינו 13 או 14 יחידות אלא רק בקפיצות של 12 … 12…24..36..48..וכן הלאה

      חוץ מזה שאפו!!!

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

        היי איציק,
        תודה רבה על התגובה, שמח לשמוע שאתה מוצא את הקוד שימושי 🙂

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

    3. עמרי שילה

      תודה רבה על מאמר מעולה
      ועוזר לי מאוד באתר ממש חיפשתי דבר כזה אז קודם כל תודה רבה
      מעריך מאוד את העבודה שלך על המאמרים האלה וההנגשה הזאת…

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

      תודה מראש
      עמרי

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

        היי עמרי,
        שמח לשמוע שאתה מוצא את המדריך שימושי 🙂

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

    4. מירי

      תודה על כל המאמרים באתר
      מועילים ומחכימים בהחלט
      האם יש אפשרות במוצר עם וארציות
      להגביל לכל ואריציה כמות אחרת?

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

        היי מירי 👋,
        תודה רבה שמח לשמוע! 🙂

        לגבי השאלה שלך, בהחלט, ממליץ לך להסתכל על איך הפילטר הזה ממומש על מנת לראות מה האופציות שלו 🙂

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

    שתפו