__('Prepare To Print Date', 'studiou-wc-ord-print-statuses'), 'in_print_date' => __('In Print Date', 'studiou-wc-ord-print-statuses'), 'external_ref_ord_date' => __('External Order Date', 'studiou-wc-ord-print-statuses'), 'external_ref_ord_delivered' => __('External Order Delivered', 'studiou-wc-ord-print-statuses'), ); } /** * Meta key → translatable label for plain text fields. */ private static function text_fields() { return array( 'external_ref_ord_no' => __('External Order Number', 'studiou-wc-ord-print-statuses'), ); } public function __construct() { add_action('woocommerce_admin_order_data_after_order_details', array($this, 'display_custom_order_fields')); add_action('woocommerce_process_shop_order_meta', array($this, 'save_custom_order_fields')); } public function display_custom_order_fields($order) { ?>

$label) { woocommerce_wp_text_input(array( 'id' => $key, 'label' => $label, 'type' => 'datetime-local', 'value' => $this->mysql_to_datetime_local($order->get_meta($key)), 'wrapper_class' => 'form-field-wide', )); } foreach (self::text_fields() as $key => $label) { woocommerce_wp_text_input(array( 'id' => $key, 'label' => $label, 'value' => $order->get_meta($key), 'wrapper_class' => 'form-field-wide', )); } ?>
update_meta_data($field, $this->datetime_local_to_mysql($_POST[$field])); } } foreach (array_keys(self::text_fields()) as $field) { if (isset($_POST[$field])) { $order->update_meta_data($field, sanitize_text_field(wp_unslash($_POST[$field]))); } } $order->save(); } /** * Convert a MySQL datetime string (as written by current_time('mysql')) to * the HTML5 `datetime-local` format. Done as pure string reformatting so * the value's timezone is preserved — current_time('mysql') already uses * WP local time, and the browser interprets datetime-local as local time. * Using strtotime()/date() here would re-interpret the value in the server * timezone and drift on UTC-server / non-UTC-site configurations. */ private function mysql_to_datetime_local($value) { $value = trim((string) $value); if ($value === '') { return ''; } // Accepts 'YYYY-MM-DD HH:MM[:SS]' or 'YYYY-MM-DDTHH:MM[:SS]'. if (preg_match('/^(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2})/', $value, $m)) { return $m[1] . 'T' . $m[2]; } return ''; } /** * Convert an HTML5 datetime-local form value to a MySQL datetime string. * No timezone conversion — the form value and the stored value are both * treated as WP local time (matching current_time('mysql')). */ private function datetime_local_to_mysql($value) { $value = sanitize_text_field(wp_unslash($value)); if ($value === '') { return ''; } if (preg_match('/^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2})(?::(\d{2}))?$/', $value, $m)) { $seconds = isset($m[3]) ? $m[3] : '00'; return $m[1] . ' ' . $m[2] . ':' . $seconds; } return ''; } }