chore: complete M1.1 runtime QA and release packaging

This commit is contained in:
XShop
2026-09-13 19:04:41 +03:30
commit f11e1d650d
66 changed files with 3094 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
defined('ABSPATH') || exit;
/**
* Template helpers.
*/
function xshop_get_setting(string $key, $default = null) {
static $cache = null;
if ($cache === null) {
$cache = get_option('xshop_settings', []);
if (!is_array($cache)) { $cache = []; }
}
return $cache[$key] ?? $default;
}
function xshop_svg(string $name, array $attrs = []): string {
$attrsStr = '';
foreach ($attrs as $k => $v) {
$attrsStr .= ' ' . esc_attr((string) $k) . '="' . esc_attr((string) $v) . '"';
}
// Sprite reference: /assets/images/sprite.svg#icon-<name>
$href = esc_url(XSHOP_THEME_URI . '/assets/images/sprite.svg#icon-' . sanitize_key($name));
return '<svg' . $attrsStr . ' aria-hidden="true"><use href="' . $href . '"></use></svg>';
}
function xshop_is_dark_mode(): bool {
$mode = xshop_get_setting('color_mode', 'light');
if ($mode === 'dark') { return true; }
if ($mode === 'auto' && isset($_COOKIE['xshop_theme'])) {
return $_COOKIE['xshop_theme'] === 'dark';
}
return false;
}
function xshop_has_woocommerce(): bool {
return class_exists('WooCommerce');
}
function xshop_is_woocommerce_page(): bool {
if (!xshop_has_woocommerce()) { return false; }
return function_exists('is_woocommerce') && (is_woocommerce() || is_cart() || is_checkout() || is_account_page());
}
function xshop_get_branding_fallback(): array {
$name = get_bloginfo('name');
$desc = get_bloginfo('description');
return [
'name' => $name ? $name : esc_html__('XShop', 'xshop'),
'desc' => $desc ? $desc : '',
];
}