<?php
/**
* @author Paul Kilmurray <paul@kilbot.com>
*
* @see http://wcpos.com
* @package WooCommerce POS
*/
namespace WCPOS\WooCommercePOS\Templates;
use Ramsey\Uuid\Uuid;
use WCPOS\WooCommercePOS\Services\Auth;
use const WCPOS\WooCommercePOS\SHORT_NAME;
use const WCPOS\WooCommercePOS\VERSION;
use const WCPOS\WooCommercePOS\PLUGIN_URL;
/**
* Frontend class.
*/
class Frontend {
/**
* @return void
*/
public function get_template(): void {
// force ssl
if ( ! is_ssl() && woocommerce_pos_get_settings( 'general', 'force_ssl' ) ) {
wp_safe_redirect( woocommerce_pos_url() );
exit;
}
// check auth
if ( ! is_user_logged_in() ) {
add_filter( 'login_url', array( $this, 'login_url' ) );
auth_redirect();
}
// check privileges
if ( ! current_user_can( 'access_woocommerce_pos' ) ) {
// translators: wordpress
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.' ) );
}
// disable cache plugins
$this->no_cache();
// last chance before frontend template is rendered
do_action( 'woocommerce_pos_frontend_template_redirect' );
/**
* Deprecated action.
*
* @TODO remove in 1.5.0
*/
if ( has_action( 'woocommerce_pos_template_redirect' ) ) {
do_action_deprecated( 'woocommerce_pos_template_redirect', array(), 'Version_1.4.0', 'woocommerce_pos_frontend_template_redirect' );
}
// add head & footer actions
add_action( 'woocommerce_pos_head', array( $this, 'head' ) );
add_action( 'woocommerce_pos_footer', array( $this, 'footer' ) );
include woocommerce_pos_locate_template( 'pos.php' );
exit;
}
/**
* Add variable to login url to signify POS login.
*
* @param $login_url
*
* @return mixed
*/
public function login_url( $login_url ) {
return add_query_arg( SHORT_NAME, '1', $login_url );
}
/**
* Output the head scripts.
*/
public function head(): void {
}
/**
* Output the footer scripts.
*/
public function footer(): void {
$development = isset( $_ENV['DEVELOPMENT'] ) && $_ENV['DEVELOPMENT'];
$user = wp_get_current_user();
$github_url = 'https://cdn.jsdelivr.net/gh/wcpos/web-bundle@1.7/';
$auth_service = Auth::instance();
$stores = array_map(
function ( $store ) {
return $store->get_data();
},
wcpos_get_stores()
);
$site_uuid = get_option( 'woocommerce_pos_uuid' );
if ( ! $site_uuid ) {
$site_uuid = Uuid::uuid4()->toString();
update_option( 'woocommerce_pos_uuid', $site_uuid );
}
$user_uuid = get_user_meta( $user->ID, '_woocommerce_pos_uuid', true );
if ( ! $user_uuid ) {
$user_uuid = Uuid::uuid4()->toString();
update_user_meta( $user->ID, '_woocommerce_pos_uuid', $user_uuid );
}
$vars = array(
'version' => VERSION,
'manifest' => $github_url . 'metadata.json',
'homepage' => woocommerce_pos_url(),
'logout_url' => $this->pos_logout_url(),
'site' => array(
'uuid' => $site_uuid,
'url' => get_option( 'siteurl' ),
'name' => get_option( 'blogname' ),
'description' => get_option( 'blogdescription' ),
'home' => home_url(),
'gmt_offset' => get_option( 'gmt_offset' ),
'timezone_string' => get_option( 'timezone_string' ),
'wp_version' => get_bloginfo( 'version' ),
'wc_version' => WC()->version,
'wcpos_version' => VERSION,
'wp_api_url' => get_rest_url(),
'wc_api_url' => get_rest_url( null, 'wc/v3' ),
'wc_api_auth_url' => get_rest_url( null, 'wcpos/v1/jwt' ),
'locale' => get_locale(),
'use_jwt_as_param' => woocommerce_pos_get_settings( 'tools', 'use_jwt_as_param' ),
),
'wp_credentials' => $auth_service->get_user_data( $user ),
'stores' => $stores,
);
/**
* Filters the javascript variables passed to the POS.
*
* @param {array} $vars
*
* @returns {array} $vars
*
* @since 1.0.0
*
* @hook woocommerce_pos_inline_vars
*/
$vars = apply_filters( 'woocommerce_pos_inline_vars', $vars );
$initial_props = wp_json_encode( $vars );
$dev_bundle = site_url( '/index.bundle?platform=web&dev=true&hot=false' );
/**
* Add path to worker scripts
*/
$idbWorker = PLUGIN_URL . 'assets/js/indexeddb.worker.js';
/**
* getScript helper and initialProps
*/
echo "<script>
function getScript(source, callback) {
var script = document.createElement('script');
script.async = true;
script.onload = script.onreadystatechange = function(_, isAbort) {
if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) {
script.onload = script.onreadystatechange = null;
script = undefined;
if (!isAbort && callback) setTimeout(callback, 0);
}
};
script.src = source;
document.head.appendChild(script);
}
function loadCSS(source, callback) {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = source;
link.onload = function() {
if (callback) callback();
};
link.onerror = function() {
console.error('Failed to load CSS file:', source);
};
document.head.appendChild(link);
}
var idbWorker = '{$idbWorker}';
var initialProps = {$initial_props};
</script>" . "\n";
/**
* The actual app bundle
*/
if ( $development ) {
// Development Mode
echo "<script>
getScript('{$dev_bundle}', function() {
console.log('Development JavaScript bundle loaded');
});
</script>" . "\n";
} else {
// Production Mode
echo "<script>
var request = new Request(initialProps.manifest);
window.fetch(request)
.then(function(response) { return response.json(); })
.then(function(data) {
var baseUrl = '{$github_url}';
var bundle = data.fileMetadata.web.bundle;
var bundleUrl = baseUrl + bundle;
// Check if CSS file is specified in the manifest
if (data.fileMetadata.web.css) {
var cssFile = data.fileMetadata.web.css;
var cssUrl = baseUrl + cssFile;
// Load CSS first
loadCSS(cssUrl, function() {
console.log('CSS loaded');
// Load JavaScript after CSS is loaded
getScript(bundleUrl, function() {
console.log('JavaScript bundle loaded');
});
});
} else {
// If no CSS file, load JavaScript immediately
getScript(bundleUrl, function() {
console.log('JavaScript bundle loaded');
});
}
})
.catch(function(error) {
console.error('Error fetching manifest:', error);
});
</script>" . "\n";
}
}
/**
*
*/
private function pos_logout_url() {
/**
* Get the login URL, allow other plugins to customise the URL. eg: WPS Hide Login
*/
$login_url = apply_filters( 'login_url', site_url( '/wp-login.php' ), 'logout', false );
$redirect_to = urlencode( woocommerce_pos_url() );
$reauth = 1;
$wcpos = 1;
$logout_nonce = wp_create_nonce( 'log-out' );
$logout_url = "{$login_url}?action=logout&_wpnonce={$logout_nonce}&redirect_to={$redirect_to}&reauth={$reauth}&wcpos={$wcpos}";
return $logout_url;
}
/**
* Disable caching conflicts.
*/
private function no_cache(): void {
// disable W3 Total Cache minify
if ( ! \defined( 'DONOTMINIFY' ) ) {
\define( 'DONOTMINIFY', 'true' );
}
// disable WP Super Cache
if ( ! \defined( 'DONOTCACHEPAGE' ) ) {
\define( 'DONOTCACHEPAGE', 'true' );
}
// disable Lite Speed Cache
do_action( 'litespeed_control_set_nocache', 'nocache WoCommerce POS web application' );
}
}