__('3D Print Showcase', '3d-print-showcase'), 'target' => 'ds82_3dps_product_data', 'class' => ['show_if_simple', 'show_if_variable', 'show_if_external', 'show_if_grouped'], 'priority' => 85, ]; return $tabs; } public function enqueue_assets(string $hook): void { if (!in_array($hook, ['post.php', 'post-new.php'], true) || 'product' !== get_current_screen()?->post_type) { return; } wp_enqueue_media(); wp_enqueue_style('ds82-3dps-admin', DS82_3DPS_URL . 'assets/css/admin.css', [], DS82_3DPS_VERSION); wp_enqueue_script('ds82-3dps-product-admin', DS82_3DPS_URL . 'assets/js/admin/product-panel.js', ['jquery'], DS82_3DPS_VERSION, true); wp_localize_script('ds82-3dps-product-admin', 'DS823DPSAdmin', [ 'titleModel' => __('Select a 3D model', '3d-print-showcase'), 'buttonModel' => __('Use this model', '3d-print-showcase'), 'titleImage' => __('Select a fallback image', '3d-print-showcase'), 'buttonImage' => __('Use this image', '3d-print-showcase'), 'remove' => __('Remove', '3d-print-showcase'), 'invalidModel' => __('Please select a valid .stl, .3mf, .glb or .gltf file.', '3d-print-showcase'), ]); } public function render_panel(): void { global $post; if (!$post instanceof \WP_Post) { return; } $productId = $post->ID; $enabled = (string) ProductMeta::get($productId, 'enabled', 'no'); $modelId = absint(ProductMeta::get($productId, 'model_attachment_id', 0)); $fallbackId = absint(ProductMeta::get($productId, 'fallback_image_id', 0)); $materialOptions = $this->material_options(); $available = ProductMeta::get($productId, 'available_materials', []); $available = is_array($available) ? array_map('strval', $available) : []; wp_nonce_field('ds82_3dps_save_product', 'ds82_3dps_product_nonce'); ?>
get_id())) { return; } $productId = $product->get_id(); ProductMeta::update($productId, 'enabled', isset($_POST['_ds82_3dps_enabled']) ? 'yes' : 'no'); $attachmentId = absint($_POST['_ds82_3dps_model_attachment_id'] ?? 0); ProductMeta::update($productId, 'model_attachment_id', $attachmentId); $modelFormat = ''; if ($attachmentId) { $attachedFile = (string) get_attached_file($attachmentId); $modelFormat = sanitize_key(strtolower((string) pathinfo($attachedFile, PATHINFO_EXTENSION))); if (!in_array($modelFormat, ['stl', '3mf', 'glb', 'gltf'], true)) { $modelFormat = ''; } } ProductMeta::update($productId, 'model_format', $modelFormat); ProductMeta::update($productId, 'default_material', sanitize_text_field(wp_unslash($_POST['_ds82_3dps_default_material'] ?? ''))); ProductMeta::update($productId, 'fallback_image_id', absint($_POST['_ds82_3dps_fallback_image_id'] ?? 0)); ProductMeta::update($productId, 'auto_rotate', isset($_POST['_ds82_3dps_auto_rotate']) ? 'yes' : 'no'); $height = absint($_POST['_ds82_3dps_height'] ?? 0); ProductMeta::update($productId, 'height', $height ? min(1200, max(240, $height)) : ''); $position = sanitize_key(wp_unslash($_POST['_ds82_3dps_position'] ?? '')); $allowed = ['', 'gallery', 'after_gallery', 'before_cart', 'after_cart', 'shortcode_only']; ProductMeta::update($productId, 'position', in_array($position, $allowed, true) ? $position : ''); if ('builtin' === Settings::get('selection_mode', 'builtin')) { $postedAvailable = filter_input(INPUT_POST, '_ds82_3dps_available_materials', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY); $available = is_array($postedAvailable) ? array_values(array_unique(array_filter(array_map('sanitize_text_field', $postedAvailable)))) : []; ProductMeta::update($productId, 'available_materials', $available); } do_action('ds82_3dps_save_product', $product); } private function material_options(): array { $options = []; foreach ($this->materials->cached() as $identifier => $material) { $options[$identifier] = $material->label(); } uasort($options, static fn (string $a, string $b): int => strnatcasecmp(trim((string) strtok($a, '-')), trim((string) strtok($b, '-')))); return $options; } }