# woocommerce-pos/1.10.16/includes/Admin/Settings.php

WCPOS – Point of Sale (POS) plugin for WooCommerce, version 1.10.16. 226 lines.

- Page: https://pluginprobe.com/plugins/woocommerce-pos/1.10.16/code/includes/Admin/Settings.php
- Raw: https://pluginprobe.com/plugins/woocommerce-pos/1.10.16/raw/includes/Admin/Settings.php
- Modified: 2026-09-11T15:59:48+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.16/code/includes/Admin/Settings.php#L10-L20`.

```php
<?php
/**
 * POS Settings.
 *
 * @author   Paul Kilmurray <paul@kilbot.com>
 *
 * @see     http://wcpos.com
 * @package WCPOS\WooCommercePOS
 */

namespace WCPOS\WooCommercePOS\Admin;

use WCPOS\WooCommercePOS\API\V1\Logs;
use WCPOS\WooCommercePOS\Services\Cloudflare_Detector;
use WCPOS\WooCommercePOS\Services\Extensions as ExtensionsService;
use WCPOS\WooCommercePOS\Services\Settings as SettingsService;
use const WCPOS\WooCommercePOS\PLUGIN_NAME;
use const WCPOS\WooCommercePOS\PLUGIN_URL;
use const WCPOS\WooCommercePOS\TRANSLATION_VERSION;
use const WCPOS\WooCommercePOS\VERSION;

/**
 * Class Settings.
 */
class Settings {
	/**
	 * Settings constructor.
	 */
	public function __construct() {
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
		add_action( 'admin_head', array( $this, 'override_wpcontent_padding' ) );
		add_action( 'in_admin_header', array( $this, 'remove_admin_notices' ) );

		/*
		 * Initializes the settings for WCPOS in the admin panel.
		 *
		 * This action hook can be used to run additional initialization routines
		 * when the WCPOS settings are being set up in the admin panel.
		 *
		 * @since 1.0.0
		 *
		 * @param Settings $this Settings class instance for the current admin context.
		 */
		do_action( 'woocommerce_pos_admin_settings_init', $this );
	}

	/**
	 * Output the settings pages.
	 */
	public static function display_settings_page(): void {
		printf(
			'<div id="woocommerce-pos-settings">
			<div id="woocommerce-pos-js-error" class="wrap">
				<h1>%s</h1>
				<p>%s <a href="mailto:support@wcpos.com">support@wcpos.com</a></p>
			</div>
		</div>',
			/* translators: Short WCPOS UI label; keep concise. */
			esc_html__( 'Error', 'woocommerce-pos' ),
			esc_html__( 'Settings failed to load, please contact support', 'woocommerce-pos' )
		);
	}

	/**
	 * Zero out #wpcontent padding so the settings page fills edge-to-edge.
	 *
	 * WordPress sets padding-left on #wpcontent, but the value varies across
	 * themes, plugins, and screen sizes. Rather than guessing the value with
	 * a negative margin hack, we remove it entirely on our settings page.
	 *
	 * @return void
	 */
	public function override_wpcontent_padding(): void {
		echo '<style>#wpcontent { padding-left: 0 !important; }</style>';
	}

	/**
	 * Remove all admin notices on our settings page.
	 *
	 * @return void
	 */
	public function remove_admin_notices(): void {
		remove_all_actions( 'admin_notices' );
		remove_all_actions( 'all_admin_notices' );
	}

	/**
	 * Enqueue assets.
	 *
	 * Note: SCRIPT_DEBUG should be set in the wp-config.php file for debugging
	 *
	 * @return void
	 */
	public function enqueue_assets(): void {
		$is_development = isset( $_ENV['DEVELOPMENT'] )
			&& wp_validate_boolean( sanitize_text_field( wp_unslash( $_ENV['DEVELOPMENT'] ) ) );
		$dir            = $is_development ? 'build' : 'assets';

		wp_enqueue_style(
			PLUGIN_NAME . '-settings-styles',
			PLUGIN_URL . $dir . '/css/settings.css',
			array(),
			VERSION
		);

		wp_enqueue_script(
			PLUGIN_NAME . '-settings',
			PLUGIN_URL . $dir . '/js/settings.js',
			array(
				'react',
				'react-dom',
				'wp-api-fetch',
				\WCPOS\WooCommercePOS\Admin::API_FETCH_METHOD_PARAM_HANDLE,
				'wp-url',
				'lodash',
			),
			VERSION,
			true
		);

		wp_add_inline_script( PLUGIN_NAME . '-settings', Menu::get_posthog_inline_script(), 'before' );

		// Add inline script.
		wp_add_inline_script( PLUGIN_NAME . '-settings', $this->inline_script(), 'before' );
	}

	/**
	 * Generate the inline script for settings.
	 *
	 * @return string
	 */
	private function inline_script(): string {
		$settings_service = SettingsService::instance();
		$barcodes         = array_values( $settings_service->get_barcodes() );
		$order_statuses   = $settings_service->get_order_statuses();
		$update_ext_count = $this->get_update_available_count();
		$unread_logs      = Logs::get_unread_counts( get_current_user_id() );
		$current_user_id  = get_current_user_id();
		$countries        = function_exists( 'WC' )
			? WC()->countries->get_countries()
			: array();
		$store_country    = function_exists( 'WC' )
			? WC()->countries->get_base_country()
			: '';
		$store_options   = apply_filters( 'woocommerce_pos_cloud_print_store_options', array() );
		$anon_id         = ( new \WCPOS\WooCommercePOS\Services\Anon_ID() )->get();
		$site_uuid       = get_option( 'woocommerce_pos_uuid', '' );

		return \sprintf(
			'var wcpos = wcpos || {}; wcpos.settings = {
            environment: %s,
            barcodes: %s,
            order_statuses: %s,
            countries: %s,
            storeCountry: %s,
            cloudPrintStoreOptions: %s,
            updateExtensionsCount: %s,
            unreadLogCounts: %s,
            currentUserId: %s,
            anon_id: %s,
            site_uuid: %s
        }; wcpos.translationVersion = %s;',
			json_encode( array( 'cloudflare' => ( new Cloudflare_Detector() )->detect() ) ),
			json_encode( $barcodes ),
			json_encode( $order_statuses ),
			json_encode( $countries ),
			json_encode( $store_country ),
			json_encode( array_values( (array) $store_options ) ),
			json_encode( $update_ext_count ),
			json_encode( $unread_logs ),
			json_encode( $current_user_id ),
			json_encode( $anon_id ),
			json_encode( $site_uuid ),
			json_encode( TRANSLATION_VERSION )
		);
	}

	/**
	 * Get the count of extensions that have updates available.
	 *
	 * Uses the cached catalog transient and local plugin versions to avoid
	 * remote fetches on every page load. Returns null if the catalog hasn't
	 * been fetched yet.
	 *
	 * @return int|null
	 */
	private function get_update_available_count(): ?int {
		$cached = get_transient( ExtensionsService::TRANSIENT_KEY );

		if ( false === $cached || ! \is_array( $cached ) ) {
			return null;
		}

		if ( ! \function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		$installed_plugins = get_plugins();
		$installed_by_slug = array();
		$count             = 0;

		foreach ( $installed_plugins as $plugin_file => $plugin_data ) {
			$parts = explode( '/', $plugin_file, 2 );
			if ( isset( $parts[1] ) ) {
				$installed_by_slug[ $parts[0] ] = $plugin_data['Version'] ?? '';
			}
		}

		foreach ( $cached as $entry ) {
			if ( ! \is_array( $entry ) ) {
				continue;
			}
			$slug       = $entry['slug'] ?? '';
			$remote_ver = $entry['latest_version'] ?? $entry['version'] ?? '';

			if ( $slug && $remote_ver && isset( $installed_by_slug[ $slug ] ) ) {
				if ( version_compare( $installed_by_slug[ $slug ], $remote_ver, '<' ) ) {
					++$count;
				}
			}
		}

		return $count;
	}
}

```
