WC_AJAX::json_search_tax_rates │ public static │ WC 1.0

Search for tax rates and return json.

Метод класса: WC_AJAX{}

Хуки из метода

Возвращает

void. Ничего (null).

Использование

$result = WC_AJAX::json_search_tax_rates();

Код WC_AJAX::json_search_tax_rates() WC 11.2.2

public static function json_search_tax_rates() {
	check_ajax_referer( 'search-tax-rates', 'security' );

	if ( ! current_user_can( 'edit_shop_orders' ) ) {
		wp_die( '-1' );
	}

	// phpcs:disable WordPress.Security.NonceVerification.Recommended
	$term = '';
	if ( isset( $_GET['term'] ) && is_scalar( $_GET['term'] ) ) {
		$clean_term = wc_clean( wp_unslash( (string) $_GET['term'] ) );
		$term       = is_string( $clean_term ) ? $clean_term : '';
	}

	$page = ! empty( $_GET['page'] ) && is_scalar( $_GET['page'] ) ? absint( wp_unslash( (string) $_GET['page'] ) ) : 1;

	/**
	 * Filters the number of results returned by the JSON search endpoints.
	 *
	 * @since 3.5.0
	 * @param int $limit Maximum number of results to return.
	 */
	$default_per_page = absint( apply_filters( 'woocommerce_json_search_limit', 30 ) );
	$per_page         = ! empty( $_GET['per_page'] ) && is_scalar( $_GET['per_page'] ) ? absint( wp_unslash( (string) $_GET['per_page'] ) ) : $default_per_page;
	// phpcs:enable WordPress.Security.NonceVerification.Recommended

	global $wpdb;

	$page            = max( 1, $page );
	$per_page        = max( 1, min( $per_page, 100 ) );
	$tax_rates       = $wpdb->prefix . 'woocommerce_tax_rates';
	$tax_locations   = $wpdb->prefix . 'woocommerce_tax_rate_locations';
	$classes         = wc_get_product_tax_class_options();
	$found_tax_rates = array();
	$join            = '';
	$where           = '';
	$distinct        = '';
	$count_select    = 'COUNT(*)';

	if ( '' !== $term ) {
		// Locations only need joining when they are actually searched, and the join is
		// what makes the DISTINCT necessary.
		$join         = "LEFT JOIN {$tax_locations} tax_locations ON tax_rates.tax_rate_id = tax_locations.tax_rate_id";
		$distinct     = 'DISTINCT ';
		$count_select = 'COUNT(DISTINCT tax_rates.tax_rate_id)';
		$conditions   = array();
		$like         = '%' . $wpdb->esc_like( $term ) . '%';

		$conditions[] = $wpdb->prepare(
			'CAST(tax_rates.tax_rate_id AS CHAR) LIKE %s
			OR tax_rates.tax_rate_name LIKE %s
			OR tax_rates.tax_rate_country LIKE %s
			OR tax_rates.tax_rate_state LIKE %s
			OR tax_rates.tax_rate_class LIKE %s
			OR tax_locations.location_code LIKE %s',
			$like,
			$like,
			$like,
			$like,
			$like,
			$like
		);

		/*
		 * The rate column stores a bare decimal (8.0000) while the modal shows a formatted
		 * percentage (8%), so strip the percent sign and any spacing before matching it.
		 */
		$rate_term = trim( str_replace( '%', '', $term ) );

		if ( '' !== $rate_term ) {
			$conditions[] = $wpdb->prepare(
				'tax_rates.tax_rate LIKE %s',
				'%' . $wpdb->esc_like( $rate_term ) . '%'
			);
		}

		/*
		 * The rate code is derived rather than stored, so rebuild it in SQL to keep
		 * WC_Tax::get_rate_code() searchable as it appears in the modal.
		 */
		$conditions[] = $wpdb->prepare(
			"UPPER(
				CONCAT_WS(
					'-',
					NULLIF( tax_rates.tax_rate_country, '' ),
					NULLIF( tax_rates.tax_rate_state, '' ),
					COALESCE( NULLIF( tax_rates.tax_rate_name, '' ), 'TAX' ),
					NULLIF( tax_rates.tax_rate_priority, 0 )
				)
			) LIKE %s",
			'%' . $wpdb->esc_like( wc_strtoupper( $term ) ) . '%'
		);

		/*
		 * Unnamed rates fall back to the store's tax or VAT label in the results table,
		 * so searching for that label needs to match them too.
		 */
		if ( false !== stripos( WC()->countries->tax_or_vat(), $term ) ) {
			$conditions[] = "tax_rates.tax_rate_name = ''";
		}

		$matching_classes  = array();
		$normalized_search = sanitize_title( $term );

		foreach ( $classes as $class_slug => $class_label ) {
			if (
				false !== stripos( $class_label, $term )
				|| (
					'' !== $normalized_search
					&& '' !== $class_slug
					&& false !== stripos( $class_slug, $normalized_search )
				)
			) {
				$matching_classes[] = $class_slug;
			}
		}

		if ( $matching_classes ) {
			$conditions[] = $wpdb->prepare(
				'tax_rates.tax_rate_class IN ( ' . implode( ', ', array_fill( 0, count( $matching_classes ), '%s' ) ) . ' )',
				$matching_classes
			);
		}

		$where = 'WHERE ( ' . implode( ' OR ', $conditions ) . ' )';
	}

	// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared
	$total       = absint(
		$wpdb->get_var(
			"
			SELECT {$count_select}
			FROM {$tax_rates} tax_rates
			{$join}
			{$where}
			"
		)
	);
	$total_pages = $total ? (int) ceil( $total / $per_page ) : 1;
	$page        = min( $page, $total_pages );
	$offset      = ( $page - 1 ) * $per_page;

	$rates = $wpdb->get_results(
		$wpdb->prepare(
			"
			SELECT {$distinct}tax_rates.*
			FROM {$tax_rates} tax_rates
			{$join}
			{$where}
			ORDER BY tax_rates.tax_rate_name, tax_rates.tax_rate_id
			LIMIT %d OFFSET %d
			",
			$per_page,
			$offset
		)
	);
	// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared

	foreach ( $rates as $rate ) {
		$tax_class = isset( $classes[ $rate->tax_rate_class ] ) ? $classes[ $rate->tax_rate_class ] : __( 'Tax', 'woocommerce' );

		$found_tax_rates[] = array(
			'id'           => absint( $rate->tax_rate_id ),
			'label'        => wp_strip_all_tags( WC_Tax::get_rate_label( $rate ) ),
			'tax_class'    => wp_strip_all_tags( $tax_class ),
			'rate_code'    => wp_strip_all_tags( WC_Tax::get_rate_code( $rate ) ),
			'rate_percent' => wp_strip_all_tags( WC_Tax::get_rate_percent( $rate ) ),
		);
	}

	wp_send_json(
		array(
			'results'    => $found_tax_rates,
			'pagination' => array(
				'page'           => $page,
				'per_page'       => $per_page,
				'total'          => $total,
				'total_pages'    => $total_pages,
				'has_prev'       => $page > 1,
				'has_next'       => $page < $total_pages,
				'displaying_num' => sprintf(
					/* translators: %s: number of tax rates. */
					_n( '%s item', '%s items', $total, 'woocommerce' ),
					number_format_i18n( $total )
				),
			),
		)
	);
}