# woocommerce-pos/1.10.4/includes/wcpos-functions.php

WCPOS – Point of Sale (POS) plugin for WooCommerce, version 1.10.4. 618 lines.

- Page: https://pluginprobe.com/plugins/woocommerce-pos/1.10.4/code/includes/wcpos-functions.php
- Raw: https://pluginprobe.com/plugins/woocommerce-pos/1.10.4/raw/includes/wcpos-functions.php
- Modified: 2026-08-25T07:52:20+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/woocommerce-pos/1.10.4/code/includes/wcpos-functions.php#L10-L20`.

```php
<?php
/**
 * Global helper functions for WCPOS.
 *
 * @author    Paul Kilmurray <paul@kilbot.com>
 *
 * @see      http://wcpos.com
 * @package WCPOS\WooCommercePOS
 */

use WCPOS\WooCommercePOS\Admin\Permalink;
use WCPOS\WooCommercePOS\Logger;
use WCPOS\WooCommercePOS\Services\Settings;
use WCPOS\WooCommercePOS\Template_Router;
use const WCPOS\WooCommercePOS\PLUGIN_PATH;
use const WCPOS\WooCommercePOS\SHORT_NAME;
use const WCPOS\WooCommercePOS\VERSION;

/*
 * ============================================================================
 * WCPOS Functions
 * ============================================================================
 *
 * Primary functions using the wcpos_ prefix.
 */

/*
 * getallheaders() is an alias of apache_response_headers()
 * This function provides compatibility for nginx servers
 */
if ( ! \function_exists( 'getallheaders' ) ) {
	/**
	 * Polyfill for getallheaders() on nginx servers.
	 *
	 * @return array The request headers.
	 */
	function getallheaders(): array { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- polyfill for missing PHP function.
		$headers = array();
		foreach ( $_SERVER as $name => $value ) {
			// RFC2616 (HTTP/1.1) defines header fields as case-insensitive entities.
			if ( 'http_' == strtolower( substr( $name, 0, 5 ) ) ) {
				$headers[ str_replace( ' ', '-', ucwords( strtolower( str_replace( '_', ' ', substr( $name, 5 ) ) ) ) ) ] = $value;
			}
		}

		return $headers;
	}
}

/*
 * Resolve the URL scheme for POS permalinks.
 *
 * @return string|null 'https' when force_ssl is enabled, null for the home scheme.
 */
if ( ! \function_exists( 'wcpos_url_scheme' ) ) {
	/**
	 * Resolve the URL scheme for POS permalinks.
	 *
	 * See Settings::url_scheme() for the policy.
	 *
	 * @return string|null 'https' when force_ssl is enabled, null for the home scheme.
	 */
	function wcpos_url_scheme(): ?string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		return Settings::instance()->url_scheme();
	}
}

/*
 * Construct the POS permalink.
 *
 * @param string $page Page slug.
 * @return string POS URL.
 */
if ( ! \function_exists( 'wcpos_url' ) ) {
	/**
	 * Construct the POS permalink.
	 *
	 * The trailing slash follows the site's permalink structure, via
	 * user_trailingslashit().
	 *
	 * @param string $page Page slug.
	 *
	 * @return string POS URL.
	 */
	function wcpos_url( $page = '' ): string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		$slug = Permalink::get_slug();

		return home_url( user_trailingslashit( $slug . '/' . $page ), wcpos_url_scheme() );
	}
}

/*
 * Construct a POS checkout permalink.
 *
 * @param string $path Path relative to the wcpos-checkout endpoint.
 * @return string POS checkout URL.
 */
if ( ! \function_exists( 'wcpos_checkout_url' ) ) {
	/**
	 * Construct a POS checkout permalink.
	 *
	 * Respects the force_ssl setting, like wcpos_url(), so checkout and receipt
	 * links work when the site home URL is http but the POS is served over https,
	 * eg: behind an SSL-terminating proxy.
	 *
	 * Like home_url(), this performs no encoding — pass trusted path segments
	 * only and escape the result on output.
	 *
	 * The trailing slash follows the site's permalink structure, via
	 * user_trailingslashit(). Slash-less URLs can trip origin rewrite rules
	 * that force a trailing slash — some redirect to a hardcoded http://
	 * target, which the browser then blocks as mixed content. The slash is
	 * appended to the end of the string, so $path must not contain a query
	 * string or fragment; append query args to the returned URL instead.
	 *
	 * @param string $path Path relative to the wcpos-checkout endpoint, eg: 'order-pay/123'.
	 *
	 * @return string POS checkout URL.
	 */
	function wcpos_checkout_url( $path = '' ): string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		$full_path = Template_Router::CHECKOUT_PATH . '/' . ltrim( $path, '/' );

		return home_url( user_trailingslashit( $full_path ), wcpos_url_scheme() );
	}
}

/*
 * Test for POS requests to the server.
 *
 * @param string $type Request type: 'query_var', 'header', or 'all'.
 * @return bool Whether this is a POS request.
 */
if ( ! \function_exists( 'wcpos_request' ) ) {
	/**
	 * Test for POS requests to the server.
	 *
	 * Core's rest_api_loaded() reads this query var, which remains the original
	 * outer route during internal re-dispatches; this behavior is load-bearing.
	 *
	 * @param string $type Request type: 'query_var', 'header', 'rest_route', or 'all'.
	 *
	 * @return bool Whether this is a POS request.
	 */
	function wcpos_request( $type = 'all' ): bool { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		// check query_vars, eg: ?wcpos=1 or /pos rewrite rule.
		if ( 'all' == $type || 'query_var' == $type ) {
			global $wp;
			if ( 1 == isset( $wp->query_vars[ SHORT_NAME ] ) && $wp->query_vars[ SHORT_NAME ] ) {
				return true;
			}
		}

		// check headers, eg: from ajax request.
		if ( 'all' == $type || 'header' == $type ) {
			$headers = array_change_key_case( getallheaders() ); // convert headers to lowercase.
			if ( 1 == isset( $headers[ 'x-' . SHORT_NAME ] ) && $headers[ 'x-' . SHORT_NAME ] ) {
				return true;
			}
		}

		if ( ( 'all' == $type || 'rest_route' == $type ) && isset( $GLOBALS['wp']->query_vars['rest_route'] ) ) {
			$route = '/' . ltrim( (string) $GLOBALS['wp']->query_vars['rest_route'], '/' );
			return 1 === preg_match( '#^/' . preg_quote( SHORT_NAME, '#' ) . '/v\d+(?:/|$)#', $route );
		}

		return false;
	}
}

/*
 * Check for POS admin requests.
 *
 * @return mixed Admin request header value or false.
 */
if ( ! \function_exists( 'wcpos_admin_request' ) ) {
	/**
	 * Check for POS admin requests.
	 *
	 * @return mixed Admin request header value or false.
	 */
	function wcpos_admin_request() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		if ( \function_exists( 'getallheaders' ) ) {
			$headers = getallheaders();
			if ( $headers && isset( $headers['X-WC-POS-ADMIN'] ) ) {
				return $headers['X-WC-POS-ADMIN'];
			}
		}
		if ( isset( $_SERVER['HTTP_X_woocommerce_pos_ADMIN'] ) ) {
			return sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_woocommerce_pos_ADMIN'] ) );
		}

		return false;
	}
}

/*
 * Helper function to get WCPOS settings.
 *
 * @param string $id  Settings ID.
 * @param string $key Optional settings key.
 * @return mixed Settings value.
 */
if ( ! \function_exists( 'wcpos_get_settings' ) ) {
	/**
	 * Helper function to get WCPOS settings.
	 *
	 * @param string $id  Settings ID.
	 * @param string $key Optional settings key.
	 *
	 * @return mixed Settings value.
	 */
	function wcpos_get_settings( $id, $key = null ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		$settings_service = Settings::instance();

		return $settings_service->get_settings( $id, $key );
	}
}

/*
 * Get the site UUID (Plugin State), generating and persisting it on first use.
 *
 * @return string Site UUID.
 */
if ( ! \function_exists( 'wcpos_get_site_uuid' ) ) {
	/**
	 * Get the site UUID, generating and persisting it on first use.
	 *
	 * Single owner for the woocommerce_pos_uuid option — the
	 * generate-if-missing logic previously lived in three places (REST index,
	 * POS frontend, analytics) and could race.
	 *
	 * @return string Site UUID.
	 */
	function wcpos_get_site_uuid(): string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		$uuid = get_option( 'woocommerce_pos_uuid', '' );
		if ( \is_string( $uuid ) && '' !== $uuid ) {
			return $uuid;
		}

		$uuid = \Ramsey\Uuid\Uuid::uuid4()->toString();

		// add_option() is a no-op when the option already exists, so a
		// concurrent request that won the race keeps its value.
		if ( ! add_option( 'woocommerce_pos_uuid', $uuid ) ) {
			$existing = get_option( 'woocommerce_pos_uuid', '' );
			if ( \is_string( $existing ) && '' !== $existing ) {
				return $existing;
			}
			update_option( 'woocommerce_pos_uuid', $uuid );
		}

		return $uuid;
	}
}

/*
 * Simple wrapper for json_encode.
 *
 * Use JSON_FORCE_OBJECT for PHP 5.3 or higher with fallback for
 * PHP less than 5.3.
 *
 * @param mixed $data Data to encode.
 * @return string|false JSON string or false on failure.
 */
if ( ! \function_exists( 'wcpos_json_encode' ) ) {
	/**
	 * Simple wrapper for json_encode with JSON_FORCE_OBJECT.
	 *
	 * @param mixed $data Data to encode.
	 *
	 * @return string|false JSON string or false on failure.
	 */
	function wcpos_json_encode( $data ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		$args = array( $data, JSON_FORCE_OBJECT );

		return \call_user_func_array( 'json_encode', $args );
	}
}

/*
 * Return template path for a given template.
 *
 * @param string $template Template name.
 * @return string|null Template path or null if not found.
 */
if ( ! \function_exists( 'wcpos_locate_template' ) ) {
	/**
	 * Return template path for a given template.
	 *
	 * @param string $template Template name.
	 *
	 * @return string|null Template path or null if not found.
	 */
	function wcpos_locate_template( $template = '' ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		// check theme directory first.
		$path = locate_template(
			array(
				'woocommerce-pos/' . $template,
			)
		);

		// if not, use plugin template.
		if ( ! $path ) {
			$path = PLUGIN_PATH . 'templates/' . $template;
		}

		/**
		 * Filters the template path.
		 *
		 * @hook woocommerce_pos_locate_template
		 *
		 * @since 1.0.0
		 *
		 * @param string $path     The full path to the template.
		 * @param string $template The template name, eg: 'receipt.php'.
		 *
		 * @return string $path The full path to the template.
		 */
		$filtered_path = apply_filters( 'woocommerce_pos_locate_template', $path, $template ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- legacy hook name.

		// Check if the filtered template file exists.
		if ( file_exists( $filtered_path ) ) {
			return $filtered_path;
		}

		// Echo a message or handle the error as needed if the file path does not exist.
		echo "The template file '" . esc_html( $filtered_path ) . "' does not exist.";

		return null;
	}
}

/*
 * Remove newlines and code spacing.
 *
 * @param string $str HTML string to trim.
 * @return string Trimmed string.
 */
if ( ! \function_exists( 'wcpos_trim_html_string' ) ) {
	/**
	 * Remove newlines and code spacing from an HTML string.
	 *
	 * @param string $str HTML string to trim.
	 *
	 * @return string Trimmed string.
	 */
	function wcpos_trim_html_string( $str ): string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		return preg_replace( '/^\s+|\n|\r|\s+$/m', '', $str );
	}
}

/*
 * Get documentation URL.
 *
 * @param string $page Documentation page.
 * @return string Documentation URL.
 */
if ( ! \function_exists( 'wcpos_doc_url' ) ) {
	/**
	 * Get documentation URL.
	 *
	 * @param string $page Documentation page.
	 *
	 * @return string Documentation URL.
	 */
	function wcpos_doc_url( $page ): string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		return 'http://docs.wcpos.com/v/' . VERSION . '/en/' . $page;
	}
}

/*
 * Get FAQ URL.
 *
 * @param string $page FAQ page.
 * @return string FAQ URL.
 */
if ( ! \function_exists( 'wcpos_faq_url' ) ) {
	/**
	 * Get FAQ URL.
	 *
	 * @param string $page FAQ page.
	 *
	 * @return string FAQ URL.
	 */
	function wcpos_faq_url( $page ): string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		return 'http://faq.wcpos.com/v/' . VERSION . '/en/' . $page;
	}
}

/*
 * Helper function to check whether an order is a POS order.
 *
 * @param \WC_Order|int $order Order object or ID.
 * @return bool Whether the order is a POS order.
 */
if ( ! \function_exists( 'wcpos_is_pos_order' ) ) {
	/**
	 * Helper function to check whether an order is a POS order.
	 *
	 * @param \WC_Order|int $order Order object or ID.
	 *
	 * @return bool Whether the order is a POS order.
	 */
	function wcpos_is_pos_order( $order ): bool { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		// Handle various input types and edge cases.
		if ( ! $order instanceof WC_Order ) {
			// Sometimes the order is passed as an ID.
			if ( is_numeric( $order ) ) {
				$order = wc_get_order( $order );
			}

			// If we still don't have a valid order, return false.
			if ( ! $order instanceof WC_Order ) {
				return false;
			}
		}

		$legacy      = $order->get_meta( '_pos', true );
		$created_via = $order->get_created_via();

		return 'woocommerce-pos' === $created_via || '1' === $legacy;
	}
}

/*
 * Get a default WooCommerce template.
 *
 * @param string $template_name Template name.
 * @param array  $args          Arguments.
 */
if ( ! \function_exists( 'wcpos_get_woocommerce_template' ) ) {
	/**
	 * Get a default WooCommerce template.
	 *
	 * @param string $template_name Template name.
	 * @param array  $args          Arguments.
	 */
	function wcpos_get_woocommerce_template( $template_name, $args = array() ): void { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
		$plugin_path = WC()->plugin_path();
		$template    = trailingslashit( $plugin_path . '/templates' ) . $template_name;

		/**
		 * Filter the default WooCommerce template path.
		 *
		 * @param string $template      Template path.
		 * @param string $template_name Template name.
		 * @param array  $args          Arguments.
		 */
		$template = apply_filters( 'wcpos_locate_woocommerce_template', $template, $template_name, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- uses wcpos_ prefix.

		if ( ! file_exists( $template ) ) {
			Logger::log( \sprintf( 'WooCommerce default template not found: %s', $template ) );

			return;
		}

		if ( $args && \is_array( $args ) ) {
			extract( $args ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
		}

		include $template;
	}
}

/*
 * ============================================================================
 * Legacy Aliases
 * ============================================================================
 *
 * These functions use the old woocommerce_pos_ prefix.
 * They are kept for backwards compatibility but new code should use wcpos_ prefix.
 *
 * @deprecated Use wcpos_* functions instead.
 */

if ( ! \function_exists( 'woocommerce_pos_url' ) ) {
	/**
	 * Legacy alias for wcpos_url().
	 *
	 * @deprecated Use wcpos_url() instead.
	 *
	 * @param mixed $page The page slug.
	 */
	function woocommerce_pos_url( $page = '' ): string {
		return wcpos_url( $page );
	}
}

if ( ! \function_exists( 'woocommerce_pos_request' ) ) {
	/**
	 * Legacy alias for wcpos_request().
	 *
	 * @deprecated Use wcpos_request() instead.
	 *
	 * @param mixed $type The request type.
	 */
	function woocommerce_pos_request( $type = 'all' ): bool {
		return wcpos_request( $type );
	}
}

if ( ! \function_exists( 'woocommerce_pos_admin_request' ) ) {
	/**
	 * Legacy alias for wcpos_admin_request().
	 *
	 * @deprecated Use wcpos_admin_request() instead.
	 */
	function woocommerce_pos_admin_request() {
		return wcpos_admin_request();
	}
}

if ( ! \function_exists( 'woocommerce_pos_get_settings' ) ) {
	/**
	 * Legacy alias for wcpos_get_settings().
	 *
	 * @deprecated Use wcpos_get_settings() instead.
	 *
	 * @param mixed      $id  The settings ID.
	 * @param null|mixed $key The settings key.
	 */
	function woocommerce_pos_get_settings( $id, $key = null ) {
		return wcpos_get_settings( $id, $key );
	}
}

if ( ! \function_exists( 'woocommerce_pos_get_anon_id' ) ) {
	/**
	 * Returns the anonymous analytics id (wcpos_anon_id), creating it on first use.
	 *
	 * Supported accessor for the Pro plugin's licence-activation request and the
	 * wcpos.com purchase reconciler join (landing-experiments spec §5.3c).
	 *
	 * @return string v4 UUID.
	 */
	function woocommerce_pos_get_anon_id(): string {
		return ( new \WCPOS\WooCommercePOS\Services\Anon_ID() )->get();
	}
}

if ( ! \function_exists( 'woocommerce_pos_json_encode' ) ) {
	/**
	 * Legacy alias for wcpos_json_encode().
	 *
	 * @deprecated Use wcpos_json_encode() instead.
	 *
	 * @param mixed $data The data to encode.
	 */
	function woocommerce_pos_json_encode( $data ) {
		return wcpos_json_encode( $data );
	}
}

if ( ! \function_exists( 'woocommerce_pos_locate_template' ) ) {
	/**
	 * Legacy alias for wcpos_locate_template().
	 *
	 * @deprecated Use wcpos_locate_template() instead.
	 *
	 * @param mixed $template The template name.
	 */
	function woocommerce_pos_locate_template( $template = '' ) {
		return wcpos_locate_template( $template );
	}
}

if ( ! \function_exists( 'woocommerce_pos_trim_html_string' ) ) {
	/**
	 * Legacy alias for wcpos_trim_html_string().
	 *
	 * @deprecated Use wcpos_trim_html_string() instead.
	 *
	 * @param mixed $str The HTML string.
	 */
	function woocommerce_pos_trim_html_string( $str ): string {
		return wcpos_trim_html_string( $str );
	}
}

if ( ! \function_exists( 'woocommerce_pos_doc_url' ) ) {
	/**
	 * Legacy alias for wcpos_doc_url().
	 *
	 * @deprecated Use wcpos_doc_url() instead.
	 *
	 * @param mixed $page The documentation page.
	 */
	function woocommerce_pos_doc_url( $page ): string {
		return wcpos_doc_url( $page );
	}
}

if ( ! \function_exists( 'woocommerce_pos_faq_url' ) ) {
	/**
	 * Legacy alias for wcpos_faq_url().
	 *
	 * @deprecated Use wcpos_faq_url() instead.
	 *
	 * @param mixed $page The FAQ page.
	 */
	function woocommerce_pos_faq_url( $page ): string {
		return wcpos_faq_url( $page );
	}
}

if ( ! \function_exists( 'woocommerce_pos_is_pos_order' ) ) {
	/**
	 * Legacy alias for wcpos_is_pos_order().
	 *
	 * @deprecated Use wcpos_is_pos_order() instead.
	 *
	 * @param mixed $order The order object or ID.
	 */
	function woocommerce_pos_is_pos_order( $order ): bool {
		return wcpos_is_pos_order( $order );
	}
}

```
