Changeset 3477410
- Timestamp:
- 03/08/2026 12:58:24 PM (4 weeks ago)
- Location:
- artinar
- Files:
-
- 5 added
- 8 edited
- 1 copied
-
assets/icon-128.png (added)
-
assets/icon-256.png (added)
-
assets/icon.svg (added)
-
assets/screenshot-1.png (added)
-
assets/screenshot-2.png (added)
-
tags/1.1 (copied) (copied from artinar/trunk)
-
tags/1.1/artinar.php (modified) (2 diffs)
-
tags/1.1/assets/js/artinar.js (modified) (2 diffs)
-
tags/1.1/includes/class-plugin.php (modified) (4 diffs)
-
tags/1.1/readme.txt (modified) (2 diffs)
-
trunk/artinar.php (modified) (2 diffs)
-
trunk/assets/js/artinar.js (modified) (3 diffs)
-
trunk/includes/class-plugin.php (modified) (4 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
artinar/tags/1.1/artinar.php
r3469138 r3477410 3 3 * Plugin Name: ArtInAR – 2D to 3D Art 4 4 * Description: Convert 2D paintings into realistic 3D canvas models that customers can preview on their wall in Augmented Reality. 5 * Version: 1. 0.05 * Version: 1.1 6 6 * Author: Roesware 7 7 * Author URI: https://roesware.nl … … 21 21 } 22 22 23 define( 'ARTINAR_VERSION', '1. 0.0' );23 define( 'ARTINAR_VERSION', '1.1' ); 24 24 define( 'ARTINAR_FILE', __FILE__ ); 25 25 define( 'ARTINAR_DIR', plugin_dir_path( __FILE__ ) ); -
artinar/tags/1.1/assets/js/artinar.js
r3469138 r3477410 169 169 } 170 170 171 function reinitContainer(container) { 172 container.__artinarInit = false; 173 initContainer(container); 174 } 175 171 176 function initAll() { 172 177 const containers = document.querySelectorAll('.art-in-ar-container'); … … 175 180 } 176 181 182 function bindVariationEvents() { 183 if (typeof jQuery === 'undefined') return; 184 185 var $form = jQuery('form.variations_form'); 186 if (!$form.length) return; 187 188 var container = document.querySelector('.art-in-ar-container'); 189 if (!container) return; 190 191 // Store original parent-level data for reset. 192 var originalData = { 193 glb: container.getAttribute('data-glb') || '', 194 usdz: container.getAttribute('data-usdz') || '', 195 link: container.getAttribute('data-link') || '' 196 }; 197 var variations = (window.artinar && artinar.variations) || {}; 198 199 $form.on('found_variation', function (event, variation) { 200 var vData = variations[variation.variation_id]; 201 if (vData) { 202 container.setAttribute('data-glb', vData.glb || ''); 203 container.setAttribute('data-usdz', vData.usdz || ''); 204 // Build a variation-specific link for the QR code. 205 var link = originalData.link.split('?')[0].split('#')[0]; 206 var params = []; 207 if (variation.attributes) { 208 for (var key in variation.attributes) { 209 if (variation.attributes[key]) { 210 params.push(encodeURIComponent(key) + '=' + encodeURIComponent(variation.attributes[key])); 211 } 212 } 213 } 214 if (params.length) { 215 link += '?' + params.join('&'); 216 } 217 container.setAttribute('data-link', link); 218 } else { 219 container.setAttribute('data-glb', originalData.glb); 220 container.setAttribute('data-usdz', originalData.usdz); 221 container.setAttribute('data-link', originalData.link); 222 } 223 reinitContainer(container); 224 }); 225 226 $form.on('reset_data', function () { 227 container.setAttribute('data-glb', originalData.glb); 228 container.setAttribute('data-usdz', originalData.usdz); 229 container.setAttribute('data-link', originalData.link); 230 reinitContainer(container); 231 }); 232 } 233 234 function init() { 235 initAll(); 236 bindVariationEvents(); 237 } 238 177 239 if (document.readyState === 'loading') { 178 document.addEventListener('DOMContentLoaded', init All);240 document.addEventListener('DOMContentLoaded', init); 179 241 } else { 180 init All();242 init(); 181 243 } 182 244 })(); -
artinar/tags/1.1/includes/class-plugin.php
r3469138 r3477410 108 108 $usdz_url = (string) get_post_meta( $pid, $usdz_key, true ); 109 109 110 if ( '' === $glb_url && '' === $usdz_url ) { 110 $has_models = ( '' !== $glb_url || '' !== $usdz_url ); 111 112 // For variable products, collect per-variation model URLs. 113 $variations_data = array(); 114 if ( $product->is_type( 'variable' ) ) { 115 foreach ( $product->get_children() as $vid ) { 116 $v_glb = $this->get_model_url( $glb_key, $vid ); 117 $v_usdz = $this->get_model_url( $usdz_key, $vid ); 118 if ( '' !== $v_glb || '' !== $v_usdz ) { 119 $has_models = true; 120 $variations_data[ $vid ] = array( 121 'glb' => $v_glb, 122 'usdz' => $v_usdz, 123 ); 124 } 125 } 126 } 127 128 if ( ! $has_models ) { 111 129 return; 112 130 } … … 137 155 ); 138 156 139 wp_localize_script( 140 'artinar', 141 'artinar', 142 array( 143 'buttonText' => (string) get_option( 'artinar_button_text', __( 'View on your wall', 'artinar' ) ), 144 'fallbackText' => (string) get_option( 'artinar_fallback_text', __( 'For the best experience, view this product in 3D on your phone.', 'artinar' ) ), 145 'enableQR' => $enable_qr, 146 'qrTitle' => (string) get_option( 'artinar_qr_title', __( 'Scan with your phone', 'artinar' ) ), 147 'qrNote' => (string) get_option( 'artinar_qr_note', __( 'Open this product on your phone to view it in AR.', 'artinar' ) ), 148 ) 149 ); 157 $localize_data = array( 158 'buttonText' => (string) get_option( 'artinar_button_text', __( 'View on your wall', 'artinar' ) ), 159 'fallbackText' => (string) get_option( 'artinar_fallback_text', __( 'For the best experience, view this product in 3D on your phone.', 'artinar' ) ), 160 'enableQR' => $enable_qr, 161 'qrTitle' => (string) get_option( 'artinar_qr_title', __( 'Scan with your phone', 'artinar' ) ), 162 'qrNote' => (string) get_option( 'artinar_qr_note', __( 'Open this product on your phone to view it in AR.', 'artinar' ) ), 163 ); 164 165 if ( ! empty( $variations_data ) ) { 166 $localize_data['variations'] = $variations_data; 167 } 168 169 wp_localize_script( 'artinar', 'artinar', $localize_data ); 150 170 151 171 wp_enqueue_script( 'artinar' ); … … 193 213 $product_id = $product->get_id(); 194 214 195 // Support ACF get_field() when available, fall back to get_post_meta(). 196 $glb_url = function_exists( 'get_field' ) ? get_field( $glb_key, $product_id ) : get_post_meta( $product_id, $glb_key, true ); 197 $usdz_url = function_exists( 'get_field' ) ? get_field( $usdz_key, $product_id ) : get_post_meta( $product_id, $usdz_key, true ); 198 199 // Ensure string type — ACF may return arrays or objects for some field types. 200 $glb_url = is_string( $glb_url ) ? $glb_url : ''; 201 $usdz_url = is_string( $usdz_url ) ? $usdz_url : ''; 215 $glb_url = $this->get_model_url( $glb_key, $product_id ); 216 $usdz_url = $this->get_model_url( $usdz_key, $product_id ); 202 217 203 218 if ( '' === $glb_url && '' === $usdz_url ) { 204 return ''; 219 // For variable products, still render the container if any variation has models. 220 if ( ! $product->is_type( 'variable' ) ) { 221 return ''; 222 } 223 $has_variation_models = false; 224 foreach ( $product->get_children() as $vid ) { 225 if ( '' !== $this->get_model_url( $glb_key, $vid ) || '' !== $this->get_model_url( $usdz_key, $vid ) ) { 226 $has_variation_models = true; 227 break; 228 } 229 } 230 if ( ! $has_variation_models ) { 231 return ''; 232 } 205 233 } 206 234 … … 458 486 459 487 /** 488 * Get a model URL from post meta, with ACF support. 489 * 490 * @param string $meta_key Meta key. 491 * @param int $post_id Post ID. 492 * @return string 493 */ 494 private function get_model_url( string $meta_key, int $post_id ): string { 495 $value = function_exists( 'get_field' ) ? get_field( $meta_key, $post_id ) : get_post_meta( $post_id, $meta_key, true ); 496 return is_string( $value ) ? $value : ''; 497 } 498 499 /** 460 500 * Sanitize boolean value. 461 501 * -
artinar/tags/1.1/readme.txt
r3469138 r3477410 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1. 0.07 Stable tag: 1.1 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 61 61 62 62 == Changelog == 63 = 1.1 = 64 * Add support for WooCommerce variable products: AR/3D models can now be set per variation. 65 * Refactor model URL retrieval into a reusable helper method. 66 63 67 = 1.0.0 = 64 68 Initial release. 65 69 66 70 == Upgrade Notice == 71 = 1.1 = 72 Adds per-variation AR/3D model support for WooCommerce variable products. 73 67 74 = 1.0.0 = 68 75 Initial stable release. -
artinar/trunk/artinar.php
r3469138 r3477410 3 3 * Plugin Name: ArtInAR – 2D to 3D Art 4 4 * Description: Convert 2D paintings into realistic 3D canvas models that customers can preview on their wall in Augmented Reality. 5 * Version: 1. 0.05 * Version: 1.1 6 6 * Author: Roesware 7 7 * Author URI: https://roesware.nl … … 21 21 } 22 22 23 define( 'ARTINAR_VERSION', '1. 0.0' );23 define( 'ARTINAR_VERSION', '1.1' ); 24 24 define( 'ARTINAR_FILE', __FILE__ ); 25 25 define( 'ARTINAR_DIR', plugin_dir_path( __FILE__ ) ); -
artinar/trunk/assets/js/artinar.js
r3469138 r3477410 153 153 container.insertBefore(androidBtn, container.firstChild); 154 154 message.textContent = ''; 155 } else if ((glbUrl || usdzUrl) ) {155 } else if ((glbUrl || usdzUrl) || (enableQR && window.artinar && artinar.variations && Object.keys(artinar.variations).length)) { 156 156 // Desktop or unsupported platform: show QR or fallback message. 157 157 if (enableQR) { … … 169 169 } 170 170 171 function reinitContainer(container) { 172 container.__artinarInit = false; 173 initContainer(container); 174 } 175 171 176 function initAll() { 172 177 const containers = document.querySelectorAll('.art-in-ar-container'); … … 175 180 } 176 181 182 function bindVariationEvents() { 183 if (typeof jQuery === 'undefined') return; 184 185 var $form = jQuery('form.variations_form'); 186 if (!$form.length) return; 187 188 var container = document.querySelector('.art-in-ar-container'); 189 if (!container) return; 190 191 // Store original parent-level data for reset. 192 var originalData = { 193 glb: container.getAttribute('data-glb') || '', 194 usdz: container.getAttribute('data-usdz') || '', 195 link: container.getAttribute('data-link') || '' 196 }; 197 var variations = (window.artinar && artinar.variations) || {}; 198 199 $form.on('found_variation', function (event, variation) { 200 var vData = variations[variation.variation_id]; 201 if (vData) { 202 container.setAttribute('data-glb', vData.glb || ''); 203 container.setAttribute('data-usdz', vData.usdz || ''); 204 // Build a variation-specific link for the QR code. 205 var link = originalData.link.split('?')[0].split('#')[0]; 206 var params = []; 207 if (variation.attributes) { 208 for (var key in variation.attributes) { 209 if (variation.attributes[key]) { 210 params.push(encodeURIComponent(key) + '=' + encodeURIComponent(variation.attributes[key])); 211 } 212 } 213 } 214 if (params.length) { 215 link += '?' + params.join('&'); 216 } 217 container.setAttribute('data-link', link); 218 } else { 219 container.setAttribute('data-glb', originalData.glb); 220 container.setAttribute('data-usdz', originalData.usdz); 221 container.setAttribute('data-link', originalData.link); 222 } 223 reinitContainer(container); 224 }); 225 226 $form.on('reset_data', function () { 227 container.setAttribute('data-glb', originalData.glb); 228 container.setAttribute('data-usdz', originalData.usdz); 229 container.setAttribute('data-link', originalData.link); 230 reinitContainer(container); 231 }); 232 } 233 234 function init() { 235 initAll(); 236 bindVariationEvents(); 237 } 238 177 239 if (document.readyState === 'loading') { 178 document.addEventListener('DOMContentLoaded', init All);240 document.addEventListener('DOMContentLoaded', init); 179 241 } else { 180 init All();242 init(); 181 243 } 182 244 })(); -
artinar/trunk/includes/class-plugin.php
r3469138 r3477410 108 108 $usdz_url = (string) get_post_meta( $pid, $usdz_key, true ); 109 109 110 if ( '' === $glb_url && '' === $usdz_url ) { 110 $has_models = ( '' !== $glb_url || '' !== $usdz_url ); 111 112 // For variable products, collect per-variation model URLs. 113 $variations_data = array(); 114 if ( $product->is_type( 'variable' ) ) { 115 foreach ( $product->get_children() as $vid ) { 116 $v_glb = $this->get_model_url( $glb_key, $vid ); 117 $v_usdz = $this->get_model_url( $usdz_key, $vid ); 118 if ( '' !== $v_glb || '' !== $v_usdz ) { 119 $has_models = true; 120 $variations_data[ $vid ] = array( 121 'glb' => $v_glb, 122 'usdz' => $v_usdz, 123 ); 124 } 125 } 126 } 127 128 if ( ! $has_models ) { 111 129 return; 112 130 } … … 137 155 ); 138 156 139 wp_localize_script( 140 'artinar', 141 'artinar', 142 array( 143 'buttonText' => (string) get_option( 'artinar_button_text', __( 'View on your wall', 'artinar' ) ), 144 'fallbackText' => (string) get_option( 'artinar_fallback_text', __( 'For the best experience, view this product in 3D on your phone.', 'artinar' ) ), 145 'enableQR' => $enable_qr, 146 'qrTitle' => (string) get_option( 'artinar_qr_title', __( 'Scan with your phone', 'artinar' ) ), 147 'qrNote' => (string) get_option( 'artinar_qr_note', __( 'Open this product on your phone to view it in AR.', 'artinar' ) ), 148 ) 149 ); 157 $localize_data = array( 158 'buttonText' => (string) get_option( 'artinar_button_text', __( 'View on your wall', 'artinar' ) ), 159 'fallbackText' => (string) get_option( 'artinar_fallback_text', __( 'For the best experience, view this product in 3D on your phone.', 'artinar' ) ), 160 'enableQR' => $enable_qr, 161 'qrTitle' => (string) get_option( 'artinar_qr_title', __( 'Scan with your phone', 'artinar' ) ), 162 'qrNote' => (string) get_option( 'artinar_qr_note', __( 'Open this product on your phone to view it in AR.', 'artinar' ) ), 163 ); 164 165 if ( ! empty( $variations_data ) ) { 166 $localize_data['variations'] = $variations_data; 167 } 168 169 wp_localize_script( 'artinar', 'artinar', $localize_data ); 150 170 151 171 wp_enqueue_script( 'artinar' ); … … 193 213 $product_id = $product->get_id(); 194 214 195 // Support ACF get_field() when available, fall back to get_post_meta(). 196 $glb_url = function_exists( 'get_field' ) ? get_field( $glb_key, $product_id ) : get_post_meta( $product_id, $glb_key, true ); 197 $usdz_url = function_exists( 'get_field' ) ? get_field( $usdz_key, $product_id ) : get_post_meta( $product_id, $usdz_key, true ); 198 199 // Ensure string type — ACF may return arrays or objects for some field types. 200 $glb_url = is_string( $glb_url ) ? $glb_url : ''; 201 $usdz_url = is_string( $usdz_url ) ? $usdz_url : ''; 215 $glb_url = $this->get_model_url( $glb_key, $product_id ); 216 $usdz_url = $this->get_model_url( $usdz_key, $product_id ); 202 217 203 218 if ( '' === $glb_url && '' === $usdz_url ) { 204 return ''; 219 // For variable products, still render the container if any variation has models. 220 if ( ! $product->is_type( 'variable' ) ) { 221 return ''; 222 } 223 $has_variation_models = false; 224 foreach ( $product->get_children() as $vid ) { 225 if ( '' !== $this->get_model_url( $glb_key, $vid ) || '' !== $this->get_model_url( $usdz_key, $vid ) ) { 226 $has_variation_models = true; 227 break; 228 } 229 } 230 if ( ! $has_variation_models ) { 231 return ''; 232 } 205 233 } 206 234 … … 458 486 459 487 /** 488 * Get a model URL from post meta, with ACF support. 489 * 490 * @param string $meta_key Meta key. 491 * @param int $post_id Post ID. 492 * @return string 493 */ 494 private function get_model_url( string $meta_key, int $post_id ): string { 495 $value = function_exists( 'get_field' ) ? get_field( $meta_key, $post_id ) : get_post_meta( $post_id, $meta_key, true ); 496 return is_string( $value ) ? $value : ''; 497 } 498 499 /** 460 500 * Sanitize boolean value. 461 501 * -
artinar/trunk/readme.txt
r3469138 r3477410 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1. 0.07 Stable tag: 1.1 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 61 61 62 62 == Changelog == 63 = 1.1 = 64 * Add support for WooCommerce variable products: AR/3D models can now be set per variation. 65 * Refactor model URL retrieval into a reusable helper method. 66 63 67 = 1.0.0 = 64 68 Initial release. 65 69 66 70 == Upgrade Notice == 71 = 1.1 = 72 Adds per-variation AR/3D model support for WooCommerce variable products. 73 67 74 = 1.0.0 = 68 75 Initial stable release.
Note: See TracChangeset
for help on using the changeset viewer.