Files
siti-wash-instructions/includes/SitiWashInstructions.php
2026-02-01 17:16:52 +00:00

337 lines
12 KiB
PHP

<?php
final class SitiWashInstructions
{
private const TAXONOMY = 'product_brand';
public static function init(): void
{
add_action('init', [__CLASS__, 'register_brand_hooks']);
add_filter('woocommerce_product_data_tabs', [__CLASS__, 'add_product_tab']);
add_action('woocommerce_product_data_panels', [__CLASS__, 'render_product_panel']);
add_action('woocommerce_process_product_meta', [__CLASS__, 'save_product_meta'], 20);
add_action('admin_head', [__CLASS__, 'admin_tab_icon']);
}
private static function fields(): array
{
return [
'temperature' => [
'label' => __('Temperatuur', 'siti-wash-instructions'),
'term_key' => 'lb_wash_temp',
'product_key' => '_lb_wash_temp',
'icon' => '🌡️',
'options' => [
'' => __('Geen advies', 'siti-wash-instructions'),
'cold' => __('Koud wassen (max 20°C)', 'siti-wash-instructions'),
'30h' => __('30°C handwas', 'siti-wash-instructions'),
'30' => __('30°C fijnwas', 'siti-wash-instructions'),
'40' => __('40°C normaal', 'siti-wash-instructions'),
'60' => __('60°C intensief', 'siti-wash-instructions'),
'hand' => __('Alleen handwas', 'siti-wash-instructions'),
],
],
'dryer' => [
'label' => __('Droger', 'siti-wash-instructions'),
'term_key' => 'lb_wash_dryer',
'product_key' => '_lb_wash_dryer',
'icon' => '🌀',
'options' => [
'' => __('Geen advies', 'siti-wash-instructions'),
'no' => __('Niet in de droger', 'siti-wash-instructions'),
'low' => __('Alleen lage stand', 'siti-wash-instructions'),
'yes' => __('Droger toegestaan', 'siti-wash-instructions'),
],
],
'iron' => [
'label' => __('Strijken', 'siti-wash-instructions'),
'term_key' => 'lb_wash_iron',
'product_key' => '_lb_wash_iron',
'icon' => '🧺',
'options' => [
'' => __('Geen advies', 'siti-wash-instructions'),
'no' => __('Niet strijken', 'siti-wash-instructions'),
'low' => __('Lage temperatuur', 'siti-wash-instructions'),
'med' => __('Gemiddelde temperatuur', 'siti-wash-instructions'),
'high' => __('Hoge temperatuur', 'siti-wash-instructions'),
],
],
'bleach' => [
'label' => __('Bleken', 'siti-wash-instructions'),
'term_key' => 'lb_wash_bleach',
'product_key' => '_lb_wash_bleach',
'icon' => '🫧',
'options' => [
'' => __('Geen advies', 'siti-wash-instructions'),
'no' => __('Niet bleken', 'siti-wash-instructions'),
'yes' => __('Alleen zuurstofbleekmiddel', 'siti-wash-instructions'),
],
],
];
}
public static function register_brand_hooks(): void
{
$tax = self::TAXONOMY;
add_action("{$tax}_add_form_fields", [__CLASS__, 'render_brand_add_form']);
add_action("{$tax}_edit_form_fields", [__CLASS__, 'render_brand_edit_form'], 10, 2);
add_action("created_{$tax}", [__CLASS__, 'save_brand_fields']);
add_action("edited_{$tax}", [__CLASS__, 'save_brand_fields']);
}
public static function render_brand_add_form($taxonomy): void
{
foreach (self::fields() as $field) {
self::render_brand_field('', $field);
}
}
public static function render_brand_edit_form($term, $taxonomy): void
{
foreach (self::fields() as $field) {
$value = (string) get_term_meta($term->term_id, $field['term_key'], true);
?>
<tr class="form-field">
<th scope="row"><label><?php echo esc_html($field['label']); ?></label></th>
<td>
<?php self::render_brand_select($field, $value); ?>
</td>
</tr>
<?php
}
}
private static function render_brand_field(string $value, array $field): void
{
?>
<div class="form-field">
<label><?php echo esc_html($field['label']); ?></label>
<?php self::render_brand_select($field, $value); ?>
</div>
<?php
}
private static function render_brand_select(array $field, string $value): void
{
?>
<select name="<?php echo esc_attr($field['term_key']); ?>" style="width:100%;">
<option value=""><?php esc_html_e('Geen advies', 'siti-wash-instructions'); ?></option>
<?php foreach ($field['options'] as $key => $label): ?>
<?php if ($key === '')
continue; ?>
<option value="<?php echo esc_attr($key); ?>" <?php selected($value, $key); ?>>
<?php echo esc_html($label); ?>
</option>
<?php endforeach; ?>
</select>
<?php
}
public static function save_brand_fields(int $term_id): void
{
foreach (self::fields() as $field) {
$key = $field['term_key'];
if (!isset($_POST[$key])) {
continue;
}
$value = sanitize_text_field(wp_unslash($_POST[$key]));
update_term_meta($term_id, $key, $value);
}
}
public static function add_product_tab(array $tabs): array
{
$tabs['lb_wash_advice'] = [
'label' => __('Wasadvies', 'siti-wash-instructions'),
'target' => 'lb_wash_advice_panel',
'class' => ['lb-wash-advice-tab', 'show_if_simple', 'show_if_variable', 'show_if_grouped', 'show_if_external'],
'priority' => 66,
];
return $tabs;
}
public static function render_product_panel(): void
{
global $post;
?>
<div id="lb_wash_advice_panel" class="panel woocommerce_options_panel">
<div class="options_group">
<?php
foreach (self::fields() as $field_key => $field) {
$product_value = get_post_meta($post->ID, $field['product_key'], true);
$options = ['inherit' => __('Volg merk (standaard)', 'siti-wash-instructions')] + $field['options'];
woocommerce_wp_select([
'id' => $field['product_key'],
'label' => $field['label'],
'value' => $product_value !== '' ? $product_value : 'inherit',
'options' => $options,
'desc_tip' => false,
'description' => __('Kies hier om het merkadvies te overschrijven.', 'siti-wash-instructions'),
]);
}
?>
</div>
</div>
<?php
}
public static function admin_tab_icon(): void
{
?>
<style>
#woocommerce-product-data ul.wc-tabs li.lb-wash-advice-tab a:before {
content: "\f19a";
font-family: Dashicons;
}
</style>
<?php
}
public static function save_product_meta(int $post_id): void
{
foreach (self::fields() as $field) {
$key = $field['product_key'];
if (!isset($_POST[$key])) {
continue;
}
$value = sanitize_text_field(wp_unslash($_POST[$key]));
update_post_meta($post_id, $key, $value);
}
}
private static function get_product_advice(int $product_id): array
{
$result = [];
foreach (self::fields() as $field_key => $field) {
$value = get_post_meta($product_id, $field['product_key'], true);
if ($value === '' || $value === 'inherit') {
$value = self::get_brand_value($product_id, $field['term_key']);
}
if ($value && isset($field['options'][$value])) {
$result[$field_key] = [
'label' => $field['label'],
'text' => $field['options'][$value],
'icon' => $field['icon'],
];
}
}
return $result;
}
private static function get_brand_value(int $product_id, string $meta_key): string
{
$terms = get_the_terms($product_id, self::TAXONOMY);
if (empty($terms) || is_wp_error($terms)) {
return '';
}
foreach ($terms as $term) {
$value = get_term_meta($term->term_id, $meta_key, true);
if ($value !== '') {
return (string) $value;
}
}
return '';
}
public static function render_frontend_block(bool $echo = true, $product = null): string
{
if ($product === null) {
global $product;
}
if (!$product instanceof WC_Product) {
return '';
}
$output = self::build_wash_markup($product);
if ($echo && $output !== '') {
echo $output;
}
return $output;
}
private static function build_wash_markup(WC_Product $product): string
{
$data = self::get_product_advice($product->get_id());
if (empty($data)) {
return '';
}
ob_start();
static $printed_styles = false;
if (!$printed_styles) {
$printed_styles = true;
?>
<style>
.lb-wash-card {
background: linear-gradient(135deg, #f0fbff, #fdf9ff);
border: 1px solid rgba(0, 140, 186, 0.2);
border-radius: 10px;
padding: 16px 18px;
margin: 16px 0;
}
.lb-wash-card__title {
font-size: 13px;
text-transform: uppercase;
letter-spacing: .5px;
color: #008cba;
font-weight: 600;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 6px;
}
.lb-wash-card__list {
list-style: none;
padding: 0;
margin: 0;
}
.lb-wash-card__list li {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 6px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
font-size: 15px;
color: #333;
}
.lb-wash-card__list li:last-child {
border-bottom: none;
}
.lb-wash-card__icon {
font-size: 18px;
}
</style>
<?php
}
?>
<div class="lb-wash-card">
<div class="lb-wash-card__title">🧼 <?php esc_html_e('Wasadvies', 'siti-wash-instructions'); ?></div>
<ul class="lb-wash-card__list">
<?php foreach ($data as $item): ?>
<li>
<span class="lb-wash-card__icon" aria-hidden="true"><?php echo esc_html($item['icon']); ?></span>
<span>
<strong><?php echo esc_html($item['label']); ?>:</strong>
<?php echo esc_html($item['text']); ?>
</span>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php
return ob_get_clean();
}
}