Plugin Directory

Changeset 3477410


Ignore:
Timestamp:
03/08/2026 12:58:24 PM (4 weeks ago)
Author:
roesware
Message:

Improvements

Location:
artinar
Files:
5 added
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • artinar/tags/1.1/artinar.php

    r3469138 r3477410  
    33 * Plugin Name: ArtInAR – 2D to 3D Art
    44 * Description: Convert 2D paintings into realistic 3D canvas models that customers can preview on their wall in Augmented Reality.
    5  * Version: 1.0.0
     5 * Version: 1.1
    66 * Author: Roesware
    77 * Author URI: https://roesware.nl
     
    2121}
    2222
    23 define( 'ARTINAR_VERSION', '1.0.0' );
     23define( 'ARTINAR_VERSION', '1.1' );
    2424define( 'ARTINAR_FILE', __FILE__ );
    2525define( 'ARTINAR_DIR', plugin_dir_path( __FILE__ ) );
  • artinar/tags/1.1/assets/js/artinar.js

    r3469138 r3477410  
    169169    }
    170170
     171    function reinitContainer(container) {
     172        container.__artinarInit = false;
     173        initContainer(container);
     174    }
     175
    171176    function initAll() {
    172177        const containers = document.querySelectorAll('.art-in-ar-container');
     
    175180    }
    176181
     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
    177239    if (document.readyState === 'loading') {
    178         document.addEventListener('DOMContentLoaded', initAll);
     240        document.addEventListener('DOMContentLoaded', init);
    179241    } else {
    180         initAll();
     242        init();
    181243    }
    182244})();
  • artinar/tags/1.1/includes/class-plugin.php

    r3469138 r3477410  
    108108        $usdz_url = (string) get_post_meta( $pid, $usdz_key, true );
    109109
    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 ) {
    111129            return;
    112130        }
     
    137155        );
    138156
    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 );
    150170
    151171        wp_enqueue_script( 'artinar' );
     
    193213        $product_id = $product->get_id();
    194214
    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 );
    202217
    203218        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            }
    205233        }
    206234
     
    458486
    459487    /**
     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    /**
    460500     * Sanitize boolean value.
    461501     *
  • artinar/tags/1.1/readme.txt

    r3469138 r3477410  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.0.0
     7Stable tag: 1.1
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    6161
    6262== 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
    6367= 1.0.0 =
    6468Initial release.
    6569
    6670== Upgrade Notice ==
     71= 1.1 =
     72Adds per-variation AR/3D model support for WooCommerce variable products.
     73
    6774= 1.0.0 =
    6875Initial stable release.
  • artinar/trunk/artinar.php

    r3469138 r3477410  
    33 * Plugin Name: ArtInAR – 2D to 3D Art
    44 * Description: Convert 2D paintings into realistic 3D canvas models that customers can preview on their wall in Augmented Reality.
    5  * Version: 1.0.0
     5 * Version: 1.1
    66 * Author: Roesware
    77 * Author URI: https://roesware.nl
     
    2121}
    2222
    23 define( 'ARTINAR_VERSION', '1.0.0' );
     23define( 'ARTINAR_VERSION', '1.1' );
    2424define( 'ARTINAR_FILE', __FILE__ );
    2525define( 'ARTINAR_DIR', plugin_dir_path( __FILE__ ) );
  • artinar/trunk/assets/js/artinar.js

    r3469138 r3477410  
    153153            container.insertBefore(androidBtn, container.firstChild);
    154154            message.textContent = '';
    155         } else if ((glbUrl || usdzUrl)) {
     155        } else if ((glbUrl || usdzUrl) || (enableQR && window.artinar && artinar.variations && Object.keys(artinar.variations).length)) {
    156156            // Desktop or unsupported platform: show QR or fallback message.
    157157            if (enableQR) {
     
    169169    }
    170170
     171    function reinitContainer(container) {
     172        container.__artinarInit = false;
     173        initContainer(container);
     174    }
     175
    171176    function initAll() {
    172177        const containers = document.querySelectorAll('.art-in-ar-container');
     
    175180    }
    176181
     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
    177239    if (document.readyState === 'loading') {
    178         document.addEventListener('DOMContentLoaded', initAll);
     240        document.addEventListener('DOMContentLoaded', init);
    179241    } else {
    180         initAll();
     242        init();
    181243    }
    182244})();
  • artinar/trunk/includes/class-plugin.php

    r3469138 r3477410  
    108108        $usdz_url = (string) get_post_meta( $pid, $usdz_key, true );
    109109
    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 ) {
    111129            return;
    112130        }
     
    137155        );
    138156
    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 );
    150170
    151171        wp_enqueue_script( 'artinar' );
     
    193213        $product_id = $product->get_id();
    194214
    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 );
    202217
    203218        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            }
    205233        }
    206234
     
    458486
    459487    /**
     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    /**
    460500     * Sanitize boolean value.
    461501     *
  • artinar/trunk/readme.txt

    r3469138 r3477410  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.0.0
     7Stable tag: 1.1
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    6161
    6262== 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
    6367= 1.0.0 =
    6468Initial release.
    6569
    6670== Upgrade Notice ==
     71= 1.1 =
     72Adds per-variation AR/3D model support for WooCommerce variable products.
     73
    6774= 1.0.0 =
    6875Initial stable release.
Note: See TracChangeset for help on using the changeset viewer.