Plugin Directory

Changeset 3789847


Ignore:
Timestamp:
11/07/2026 03:49:49 PM (4 hours ago)
Author:
knaldi2020
Message:

Created tag 1.2.0.

Location:
productsize-chart-for-woocommerce/tags/1.2.0
Files:
1 deleted
9 edited
3 copied

Legend:

Unmodified
Added
Removed
  • productsize-chart-for-woocommerce/tags/1.2.0/admin/class-productsize-chart-admin.php

    r2595861 r3789847  
    7272                $this->plugin_name                = $plugin_name;
    7373                $this->version                    = $version;
    74                 $this->productsize_chart_settings = get_option( 'productsize_chart_settings', array() );
    75 
    76                 if ( empty( $this->productsize_chart_settings ) ) {
     74                $saved = get_option( 'productsize_chart_settings', array() );
     75                if ( empty( $saved ) || ! is_array( $saved ) ) {
    7776                        $this->productsize_chart_default_settings();
     77                } else {
     78                        $this->productsize_chart_settings = wp_parse_args( $saved, self::default_settings() );
    7879                }
    7980
    … …  
    164165
    165166        /**
    166          * Save the meta when the post is saved.
    167          *
    168          * @param int $post_id The ID of the post being saved.
     167         * Read a posted text value. The save handlers verify the nonce before calling this.
     168         *
     169         * @param string $key     POST key.
     170         * @param string $default Fallback when the key is missing.
     171         * @return string
     172         */
     173        private function get_posted_text( $key, $default = '' ) {
     174                // phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce is verified by the calling save handler.
     175                if ( ! isset( $_POST[ $key ] ) || is_array( $_POST[ $key ] ) ) {
     176                        return $default;
     177                }
     178                return sanitize_text_field( wp_unslash( $_POST[ $key ] ) );
     179                // phpcs:enable WordPress.Security.NonceVerification.Missing
     180        }
     181
     182        /**
     183         * Read a posted value that must be one of the allowed choices.
     184         *
     185         * @param string $key     POST key.
     186         * @param array  $allowed Allowed values.
     187         * @param string $default Fallback.
     188         * @return string
     189         */
     190        private function get_posted_choice( $key, $allowed, $default ) {
     191                $value = $this->get_posted_text( $key, $default );
     192                return in_array( $value, $allowed, true ) ? $value : $default;
     193        }
     194
     195        /**
     196         * Read a posted hex colour. Returns the fallback when the value is not a valid hex colour.
     197         *
     198         * @param string $key     POST key.
     199         * @param string $default Fallback.
     200         * @return string
     201         */
     202        private function get_posted_color( $key, $default = '' ) {
     203                $color = sanitize_hex_color( $this->get_posted_text( $key ) );
     204                return $color ? $color : $default;
     205        }
     206
     207        /**
     208         * Read a posted chart table (JSON list of rows). Anything that is not a JSON list is dropped.
     209         *
     210         * @param string $key POST key.
     211         * @return string
     212         */
     213        private function get_posted_table( $key ) {
     214                $table = $this->get_posted_text( $key );
     215                if ( '' === $table || ! is_array( json_decode( $table ) ) ) {
     216                        return '';
     217                }
     218                return $table;
     219        }
     220
     221        /**
     222         * Read posted rich text (editor content).
     223         *
     224         * @param string $key POST key.
     225         * @return string
     226         */
     227        private function get_posted_html( $key ) {
     228                // phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce is verified by the calling save handler.
     229                if ( ! isset( $_POST[ $key ] ) || is_array( $_POST[ $key ] ) ) {
     230                        return '';
     231                }
     232                return wp_kses_post( wp_unslash( $_POST[ $key ] ) );
     233                // phpcs:enable WordPress.Security.NonceVerification.Missing
     234        }
     235
     236        /**
     237         * Store post meta. update_post_meta() expects slashed data, so values are slashed first.
     238         *
     239         * @param int    $post_id Post ID.
     240         * @param string $key     Meta key.
     241         * @param mixed  $value   Meta value.
     242         */
     243        private function update_meta( $post_id, $key, $value ) {
     244                update_post_meta( $post_id, $key, wp_slash( $value ) );
     245        }
     246
     247        /**
     248         * Checks shared by the save handlers: valid nonce, no autosave/revision, right post type, capability.
     249         *
     250         * @param int    $post_id   Post ID.
     251         * @param string $field     Nonce field name (also the nonce action).
     252         * @param string $post_type Required post type.
     253         * @return bool
     254         */
     255        private function can_save( $post_id, $field, $post_type ) {
     256                // phpcs:disable WordPress.Security.NonceVerification.Missing -- this is the nonce check.
     257                if ( ! isset( $_POST[ $field ] ) || is_array( $_POST[ $field ] ) ) {
     258                        return false;
     259                }
     260                $nonce = sanitize_text_field( wp_unslash( $_POST[ $field ] ) );
     261                // phpcs:enable WordPress.Security.NonceVerification.Missing
     262                if ( ! wp_verify_nonce( $nonce, $field ) ) {
     263                        return false;
     264                }
     265                if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
     266                        return false;
     267                }
     268                if ( wp_is_post_revision( $post_id ) || get_post_type( $post_id ) !== $post_type ) {
     269                        return false;
     270                }
     271                return current_user_can( 'edit_post', $post_id );
     272        }
     273
     274        /**
     275         * Normalise the meta of an additional chart (1 or 2).
     276         *
     277         * Chart 2 used to be stored under keys with a "-1" suffix and the image position of
     278         * both charts under inconsistent keys. This reads the current keys and falls back
     279         * to the legacy ones so charts saved by older versions keep working.
     280         *
     281         * @param mixed $meta Raw meta value of "chart-1" / "chart-2".
     282         * @param int   $n    Chart number (1 or 2).
     283         * @return array {title, image, position, content, table}
     284         */
     285        public static function normalize_extra_chart( $meta, $n ) {
     286                $meta   = is_array( $meta ) ? $meta : array();
     287                $legacy = ( 2 === (int) $n ) ? '-1' : '';
     288                $get    = static function ( $key ) use ( $meta, $legacy ) {
     289                        if ( isset( $meta[ $key ] ) ) {
     290                                return $meta[ $key ];
     291                        }
     292                        if ( '' !== $legacy && isset( $meta[ $key . $legacy ] ) ) {
     293                                return $meta[ $key . $legacy ];
     294                        }
     295                        return '';
     296                };
     297                $position = $get( 'chart-position' );
     298                if ( '' === $position ) {
     299                        $position = $get( 'image-position' );
     300                }
     301                return array(
     302                        'title'    => (string) $get( 'chart-title' ),
     303                        'image'    => absint( $get( 'chart-image' ) ),
     304                        'position' => 'left' === $position ? 'left' : 'right',
     305                        'content'  => (string) $get( 'chart-content' ),
     306                        'table'    => (string) $get( 'chart-table' ),
     307                );
     308        }
     309
     310        /**
     311         * Save the chart settings of a "chart" post.
     312         *
     313         * @param int $post_id Post ID.
    169314         */
    170315        public function productsize_chart_save( $post_id ) {
    171 
    172                 // Check if our nonce is set.
    173                 if ( ! isset( $_POST['productsize_chart_inner_custom_box'] ) ) {
     316                if ( ! $this->can_save( $post_id, 'productsize_chart_inner_custom_box', 'chart' ) ) {
    174317                        return $post_id;
    175318                }
    176319
    177                 $nonce = $_POST['productsize_chart_inner_custom_box'];
    178 
    179                 // Verify that the nonce is valid.
    180                 if ( ! wp_verify_nonce( $nonce, 'productsize_chart_inner_custom_box' ) ) {
     320                // phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce verified in can_save().
     321                $categories = ( isset( $_POST['chart-categories'] ) && is_array( $_POST['chart-categories'] ) ) ? array_map( 'absint', wp_unslash( $_POST['chart-categories'] ) ) : array();
     322                // phpcs:enable WordPress.Security.NonceVerification.Missing
     323
     324                $chart_position = $this->get_posted_choice( 'position', array( 'tab', 'popup' ), 'tab' );
     325                $padding        = $this->get_posted_text( 'chart-padding' );
     326
     327                $this->update_meta( $post_id, 'label', $this->get_posted_text( 'label' ) );
     328                $this->update_meta( $post_id, 'primary-chart-image', absint( $this->get_posted_text( 'primary-chart-image' ) ) );
     329                $this->update_meta( $post_id, 'primary-image-position', $this->get_posted_choice( 'primary-image-position', array( 'left', 'right' ), 'left' ) );
     330                $this->update_meta( $post_id, 'title-color', $this->get_posted_color( 'title-color' ) );
     331                $this->update_meta( $post_id, 'text-color', $this->get_posted_color( 'text-color' ) );
     332                $this->update_meta( $post_id, 'overlay-color', $this->get_posted_color( 'overlay-color' ) );
     333                $this->update_meta( $post_id, 'table-style', $this->get_posted_choice( 'table-style', array( 'style-1', 'style-2' ), 'style-1' ) );
     334                // Padding is a number of pixels; "px" is added on output.
     335                $this->update_meta( $post_id, 'chart-padding', '' === $padding ? '' : (string) absint( $padding ) );
     336                $this->update_meta( $post_id, 'position', $chart_position );
     337                if ( 'tab' !== $chart_position ) {
     338                        $this->update_meta(
     339                                $post_id,
     340                                'button-position',
     341                                $this->get_posted_choice( 'button-position', array( 'before-summary-text', 'after-add-to-cart', 'before-add-to-cart', 'after-product-meta' ), 'after-add-to-cart' )
     342                        );
     343                }
     344                $this->update_meta( $post_id, 'chart-categories', $categories );
     345                $this->update_meta( $post_id, 'chart-table', $this->get_posted_table( 'chart-table' ) );
     346
     347                if ( 1 === (int) $this->productsize_chart_settings['productsize-chart-enable-additional-chart'] ) {
     348                        foreach ( array( 1, 2 ) as $n ) {
     349                                $this->update_meta(
     350                                        $post_id,
     351                                        'chart-' . $n,
     352                                        array(
     353                                                'chart-title'    => $this->get_posted_text( 'chart-title-' . $n ),
     354                                                'chart-image'    => absint( $this->get_posted_text( 'chart-image-' . $n ) ),
     355                                                'chart-position' => $this->get_posted_choice( 'image-position-' . $n, array( 'left', 'right' ), 'left' ),
     356                                                'chart-content'  => $this->get_posted_html( 'chart-content-' . $n ),
     357                                                'chart-table'    => $this->get_posted_table( 'chart-table-' . $n ),
     358                                        )
     359                                );
     360                        }
     361                }
     362
     363                return $post_id;
     364        }
     365
     366        /**
     367         * Save the chart that is selected on a product.
     368         *
     369         * @param int $post_id Post ID.
     370         */
     371        public function productsize_chart_select_save( $post_id ) {
     372                if ( ! $this->can_save( $post_id, 'productsize_chart_select_custom_box', 'product' ) ) {
    181373                        return $post_id;
    182374                }
    183375
    184                 // If this is an autosave, our form has not been submitted,
    185                 // so we don't want to do anything.
    186                 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
    187                         return $post_id;
    188                 }
    189 
    190                 // Check the user's permissions.
    191                 if ( 'chart' == $_POST['post_type'] ) {
    192 
    193                         if ( ! current_user_can( 'edit_page', $post_id ) ) {
    194                                 return $post_id;
    195                         }
    196                 } else {
    197 
    198                         if ( ! current_user_can( 'edit_post', $post_id ) ) {
    199                                 return $post_id;
    200                         }
    201                 }
    202 
    203                 /* OK, its safe for us to save the data now. */
    204 
    205                 if ( isset( $_POST['prod-chart'] ) ) {
    206                         $chart_id = sanitize_text_field( $_POST['prod-chart'] );
    207                         update_post_meta( $post_id, 'prod-chart', $chart_id );
    208                         return;
    209                 }
    210 
    211                 $categories = $_POST['chart-categories'];
    212                 if ( ! is_array( $categories ) ) {
    213                         $categories = array();
    214                 }
    215 
    216                 // Sanitize the user input.
    217                 $chart_label        = sanitize_text_field( $_POST['label'] );
    218                 $chart_img          = absint( $_POST['primary-chart-image'] );
    219                 $chart_img_position = sanitize_text_field( $_POST['primary-image-position'] );
    220                 $title_color        = sanitize_text_field( $_POST['title-color'] );
    221                 $text_color         = sanitize_text_field( $_POST['text-color'] );
    222                 $overlay_color      = sanitize_text_field( $_POST['overlay-color'] );
    223                 $table_style        = sanitize_text_field( $_POST['table-style'] );
    224                 $chart_padding      = sanitize_text_field( $_POST['chart-padding'] );
    225                 $chart_position     = sanitize_text_field( $_POST['position'] );
    226                 $button_position    = sanitize_text_field( $_POST['button-position'] );
    227                 $chart_categories   = array_map( 'absint', $categories );
    228                 $chart_table        = sanitize_text_field( $_POST['chart-table'] );
    229 
    230                 // update chart meta
    231                 update_post_meta( $post_id, 'label', $chart_label );
    232                 update_post_meta( $post_id, 'primary-chart-image', $chart_img );
    233                 update_post_meta( $post_id, 'primary-image-position', $chart_img_position );
    234                 update_post_meta( $post_id, 'title-color', $title_color );
    235                 update_post_meta( $post_id, 'text-color', $text_color );
    236                 update_post_meta( $post_id, 'overlay-color', $overlay_color );
    237                 update_post_meta( $post_id, 'table-style', $table_style );
    238                 update_post_meta( $post_id, 'chart-padding', $chart_padding );
    239                 update_post_meta( $post_id, 'position', $chart_position );
    240 
    241                 if ( 'tab' != $chart_position ) {
    242                         update_post_meta( $post_id, 'button-position', $button_position );
    243                 }
    244                 update_post_meta( $post_id, 'chart-categories', $chart_categories );
    245                 update_post_meta( $post_id, 'chart-table', $chart_table );
    246 
    247                 if ( 1 == $this->productsize_chart_settings['productsize-chart-enable-additional-chart'] ) {
    248 
    249                         // chart 1
    250                         $chart_1                   = array();
    251                         $chart_1['chart-title']    = sanitize_text_field( $_POST['chart-title-1'] );
    252                         $chart_1['chart-image']    = absint( $_POST['chart-image-1'] );
    253                         $chart_1['chart-position'] = sanitize_text_field( $_POST['chart-position-1'] );
    254                         $chart_1['chart-content']  = sanitize_text_field( $_POST['chart-content-1'] );
    255                         $chart_1['chart-table']    = sanitize_text_field( $_POST['chart-table-1'] );
    256                         update_post_meta( $post_id, 'chart-1', $chart_1 );
    257 
    258                         // chart 2
    259                         $chart_2                     = array();
    260                         $chart_2['chart-title-1']    = sanitize_text_field( $_POST['chart-title-2'] );
    261                         $chart_2['chart-image-1']    = absint( $_POST['chart-image-2'] );
    262                         $chart_2['chart-position-1'] = sanitize_text_field( $_POST['chart-position-2'] );
    263                         $chart_2['chart-content-1']  = sanitize_text_field( $_POST['chart-content-2'] );
    264                         $chart_2['chart-table-1']    = sanitize_text_field( $_POST['chart-table-2'] );
    265                         update_post_meta( $post_id, 'chart-2', $chart_2 );
    266 
    267                 }
    268         }
    269 
    270 
    271         /**
    272          * Save the meta when the post is saved.
    273          *
    274          * @param int $post_id The ID of the post being saved.
    275          */
    276         public function productsize_chart_select_save( $post_id ) {
    277 
    278                 // Check if our nonce is set.
    279                 if ( ! isset( $_POST['productsize_chart_select_custom_box'] ) ) {
    280                         return $post_id;
    281                 }
    282 
    283                 $nonce = $_POST['productsize_chart_select_custom_box'];
    284 
    285                 // Verify that the nonce is valid.
    286                 if ( ! wp_verify_nonce( $nonce, 'productsize_chart_select_custom_box' ) ) {
    287                         return $post_id;
    288                 }
    289 
    290                 // If this is an autosave, our form has not been submitted,
    291                 // so we don't want to do anything.
    292                 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
    293                         return $post_id;
    294                 }
    295 
    296                 // Check the user's permissions.
    297                 if ( 'product' == $_POST['post_type'] ) {
    298 
    299                         if ( ! current_user_can( 'edit_page', $post_id ) ) {
    300                                 return $post_id;
    301                         }
    302                 } else {
    303 
    304                         if ( ! current_user_can( 'edit_post', $post_id ) ) {
    305                                 return $post_id;
    306                         }
    307                 }
    308 
    309                 /* OK, its safe for us to save the data now. */
    310 
    311                 if ( isset( $_POST['prod-chart'] ) ) {
    312                         $chart_id = sanitize_text_field( $_POST['prod-chart'] );
    313                         update_post_meta( $post_id, 'prod-chart', $chart_id );
    314                         return;
    315                 }
    316 
    317         }
    318 
     376                $chart_id = absint( $this->get_posted_text( 'prod-chart' ) );
     377                $this->update_meta( $post_id, 'prod-chart', $chart_id ? $chart_id : '' );
     378
     379                return $post_id;
     380        }
    319381
    320382        /**
    … …  
    377439                        wp_enqueue_media();
    378440
    379                         // Registers and enqueues the required javascript.
    380                         wp_register_script( 'meta-box-image', plugin_dir_url( __FILE__ ) . '/assets/js/custom-script.js', array( 'jquery' ) );
    381                         wp_localize_script(
    382                                 'meta-box-image',
    383                                 'meta_image',
    384                                 array(
    385                                         'title'  => esc_html__( 'Upload an Image', 'productsize-chart-for-woocommerce' ),
    386                                         'button' => esc_html__( 'Use this image', 'productsize-chart-for-woocommerce' ),
    387                                 )
    388                         );
    389                         wp_enqueue_script( 'meta-box-image' );
    390                 }
    391         }
    392 
    393 
    394 
    395          /**
    396           * Default setting values for size chart
    397           * * @since      1.0.0
    398           */
     441                }
     442        }
     443
     444
     445
     446        /**
     447         * The default plugin settings.
     448         *
     449         * @return array
     450         */
     451        public static function default_settings() {
     452                return array(
     453                        'productsize-chart-title'                  => 'h2',
     454                        'productsize-chart-enable-additional-chart' => '1',
     455                        'productsize-chart-additional-title'       => '',
     456                        'productsize-chart-title-color'            => '#000000',
     457                        'productsize-chart-text-color'             => '#000000',
     458                        'productsize-chart-table-style'            => 'style-1',
     459                        'productsize-chart-button-bg-color'        => '#000000',
     460                        'productsize-chart-button-hover-bg'        => '#333333',
     461                        'productsize-chart-button-text-color'      => '#ffffff',
     462                        'productsize-chart-overlay-color'          => '#000000',
     463                        'productsize-chart-overlay-opacity'        => '0.7',
     464                        'productsize-chart-button-class'           => '',
     465                        'productsize-chart-button-label'           => 'Size Guide',
     466                        // Optional "Size chart by Sizegram" link. Opt-in: off unless the site owner turns it on.
     467                        'productsize-chart-show-credit'            => 0,
     468                );
     469        }
     470
     471        /**
     472         * Store the default settings.
     473         */
    399474        public function productsize_chart_default_settings() {
    400 
    401                 $this->productsize_chart_default_settings                            = array();
    402                 $this->productsize_chart_default_settings['productsize-chart-title'] = 'h2';
    403                 $this->productsize_chart_default_settings['productsize-chart-enable-additional-chart'] = '1';
    404                 $this->productsize_chart_default_settings['productsize-chart-additional-title']        = '';
    405                 $this->productsize_chart_default_settings['productsize-chart-title-color']             = '#000000';
    406                 $this->productsize_chart_default_settings['productsize-chart-text-color']              = '#000000';
    407                 $this->productsize_chart_default_settings['productsize-chart-table-style']             = 'style-1';
    408                 $this->productsize_chart_default_settings['productsize-chart-button-bg-color']         = '#000000';
    409                 $this->productsize_chart_default_settings['productsize-chart-button-hover-bg']         = '#333333';
    410                 $this->productsize_chart_default_settings['productsize-chart-button-text-color']       = '#ffffff';
    411                 $this->productsize_chart_default_settings['productsize-chart-overlay-color']           = '#000000';
    412                 $this->productsize_chart_default_settings['productsize-chart-overlay-opacity']         = '0.7';
    413                 $this->productsize_chart_default_settings['productsize-chart-button-class']            = '';
    414                 $this->productsize_chart_default_settings['productsize-chart-button-label']            = 'Size Guide';
    415                
     475                $this->productsize_chart_default_settings = self::default_settings();
     476                $this->productsize_chart_settings         = $this->productsize_chart_default_settings;
    416477                update_option( 'productsize_chart_settings', $this->productsize_chart_default_settings );
    417 
    418478        }
    419479
    … …  
    428488
    429489        public function productsize_chart_settings_page() {
     490                // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce is verified right below.
    430491                if ( isset( $_POST['productsize_chart_submit'] ) ) {
    431492                        check_admin_referer( 'productsize_chart_page' );
     493                        if ( ! current_user_can( 'manage_options' ) ) {
     494                                wp_die( esc_html__( 'You do not have permission to change these settings.', 'productsize-chart-for-woocommerce' ), '', array( 'response' => 403 ) );
     495                        }
    432496                        $this->productsize_chart_save_settings();
    433                         wp_redirect( admin_url( 'edit.php?post_type=chart&page=productsize_chart' ) );
     497                        wp_safe_redirect( admin_url( 'edit.php?post_type=chart&page=productsize_chart' ) );
    434498                        exit;
    435499                }
    436500        }
    437 
    438 
    439501
    440502        /**
    … …  
    459521
    460522        public function productsize_chart_save_settings() {
    461 
    462                 if ( ! isset( $_GET['page'] ) ) {
    463                         return;
    464                 }
    465 
    466                 $this->productsize_chart_settings = array();
    467                 if ( 'productsize_chart' == $_GET['page'] ) {
    468 
    469                         $this->productsize_chart_settings                            = array();
    470                         $this->productsize_chart_settings['productsize-chart-title'] = sanitize_text_field( $_POST['productsize-chart-title'] );
    471                         $this->productsize_chart_settings['productsize-chart-enable-additional-chart'] = isset( $_POST['productsize-chart-enable-additional-chart'] ) ? 1 : 0;
    472                         $this->productsize_chart_settings['productsize-chart-additional-title']        = sanitize_text_field( $_POST['productsize-chart-additional-title'] );
    473                         $this->productsize_chart_settings['productsize-chart-title-color']             = sanitize_hex_color( $_POST['productsize-chart-title-color'] );
    474                         $this->productsize_chart_settings['productsize-chart-text-color']              = sanitize_hex_color( $_POST['productsize-chart-text-color'] );
    475                         $this->productsize_chart_settings['productsize-chart-table-style']             = sanitize_text_field( $_POST['productsize-chart-table-style'] );
    476                         $this->productsize_chart_settings['productsize-chart-button-bg-color']         = sanitize_hex_color( $_POST['productsize-chart-button-bg-color'] );
    477                         $this->productsize_chart_settings['productsize-chart-button-hover-bg']         = sanitize_hex_color( $_POST['productsize-chart-button-hover-bg'] );
    478                         $this->productsize_chart_settings['productsize-chart-button-text-color']       = sanitize_hex_color( $_POST['productsize-chart-button-text-color'] );
    479                         $this->productsize_chart_settings['productsize-chart-overlay-color']           = sanitize_hex_color( $_POST['productsize-chart-overlay-color'] );
    480                         $this->productsize_chart_settings['productsize-chart-overlay-opacity']         = sanitize_text_field( $_POST['productsize-chart-overlay-opacity'] );
    481                         $this->productsize_chart_settings['productsize-chart-button-class']            = sanitize_text_field( $_POST['productsize-chart-button-class'] );
    482                         $this->productsize_chart_settings['productsize-chart-button-label']            = sanitize_text_field( $_POST['productsize-chart-button-label'] );
    483 
    484                         // update option
    485                         update_option( 'productsize_chart_settings', $this->productsize_chart_settings );
    486 
    487                 }
     523                // Called from productsize_chart_settings_page() after the nonce and capability checks.
     524                $defaults = self::default_settings();
     525                $current  = wp_parse_args( $this->productsize_chart_settings, $defaults );
     526                $classes  = array_filter( array_map( 'sanitize_html_class', explode( ' ', $this->get_posted_text( 'productsize-chart-button-class' ) ) ) );
     527                $opacity  = (float) $this->get_posted_text( 'productsize-chart-overlay-opacity', $current['productsize-chart-overlay-opacity'] );
     528                $label    = $this->get_posted_text( 'productsize-chart-button-label' );
     529
     530                // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified in productsize_chart_settings_page().
     531                $additional = isset( $_POST['productsize-chart-enable-additional-chart'] ) ? 1 : 0;
     532                // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified in productsize_chart_settings_page().
     533                $credit = isset( $_POST['productsize-chart-show-credit'] ) ? 1 : 0;
     534
     535                $settings = array(
     536                        'productsize-chart-title'                   => $this->get_posted_choice( 'productsize-chart-title', array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), $defaults['productsize-chart-title'] ),
     537                        'productsize-chart-enable-additional-chart' => $additional,
     538                        'productsize-chart-additional-title'        => $this->get_posted_choice( 'productsize-chart-additional-title', array( '', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), '' ),
     539                        'productsize-chart-title-color'             => $this->get_posted_color( 'productsize-chart-title-color', $current['productsize-chart-title-color'] ),
     540                        'productsize-chart-text-color'              => $this->get_posted_color( 'productsize-chart-text-color', $current['productsize-chart-text-color'] ),
     541                        'productsize-chart-table-style'             => $this->get_posted_choice( 'productsize-chart-table-style', array( 'style-1', 'style-2' ), $defaults['productsize-chart-table-style'] ),
     542                        'productsize-chart-button-bg-color'         => $this->get_posted_color( 'productsize-chart-button-bg-color', $current['productsize-chart-button-bg-color'] ),
     543                        'productsize-chart-button-hover-bg'         => $this->get_posted_color( 'productsize-chart-button-hover-bg', $current['productsize-chart-button-hover-bg'] ),
     544                        'productsize-chart-button-text-color'       => $this->get_posted_color( 'productsize-chart-button-text-color', $current['productsize-chart-button-text-color'] ),
     545                        'productsize-chart-overlay-color'           => $this->get_posted_color( 'productsize-chart-overlay-color', $current['productsize-chart-overlay-color'] ),
     546                        'productsize-chart-overlay-opacity'         => (string) max( 0, min( 1, $opacity ) ),
     547                        'productsize-chart-button-class'            => implode( ' ', $classes ),
     548                        'productsize-chart-button-label'            => '' === $label ? $defaults['productsize-chart-button-label'] : $label,
     549                        'productsize-chart-show-credit'             => $credit,
     550                );
     551
     552                $this->productsize_chart_settings = $settings;
     553                update_option( 'productsize_chart_settings', $settings );
    488554        }
    489555
    … …  
    544610                wp_enqueue_script( $this->plugin_name . '-jquery-editable-js', plugin_dir_url( __FILE__ ) . 'js/jquery.edittable.js', array( 'jquery' ), $this->version, false );
    545611                wp_enqueue_script( $this->plugin_name . '-jquery-select2', plugin_dir_url( __FILE__ ) . 'js/select2.min.js', array( 'jquery' ), $this->version, false );
    546                 wp_enqueue_script( $this->plugin_name . '-custom-script', plugins_url( 'js/custom-script.js', __FILE__ ), array( 'wp-color-picker' ), false, true );
     612                wp_enqueue_script( $this->plugin_name . '-custom-script', plugins_url( 'js/custom-script.js', __FILE__ ), array( 'jquery', 'wp-color-picker' ), $this->version, true );
     613                wp_localize_script(
     614                        $this->plugin_name . '-custom-script',
     615                        'meta_image',
     616                        array(
     617                                'title'  => esc_html__( 'Upload an Image', 'productsize-chart-for-woocommerce' ),
     618                                'button' => esc_html__( 'Use this image', 'productsize-chart-for-woocommerce' ),
     619                        )
     620                );
    547621
    548622        }
  • productsize-chart-for-woocommerce/tags/1.2.0/admin/includes/productsize-chart-add-meta-form.php

    r2545262 r3789847  
    1515}
    1616
    17 // Use get_post_meta to retrieve an existing value of chart 1 from the database.
    18 $chart1_assets       = get_post_meta( $post->ID, 'chart-1', false );
    19 $chart1_title        = '';
    20 $chart1_img          = '';
    21 $chart1_img_position = '';
    22 $chart1_content      = '';
    23 $chart1_table        = '';
     17// Use get_post_meta to retrieve the existing values of the additional charts.
     18$chart1 = productsize_chart_Admin::normalize_extra_chart( get_post_meta( $post->ID, 'chart-1', true ), 1 );
     19$chart2 = productsize_chart_Admin::normalize_extra_chart( get_post_meta( $post->ID, 'chart-2', true ), 2 );
    2420
    25 if ( ! empty( $chart1_assets ) ) {
    26         $chart = $chart1_assets[0];
     21$chart1_title        = $chart1['title'];
     22$chart1_img          = $chart1['image'];
     23$chart1_img_position = $chart1['position'];
     24$chart1_content      = $chart1['content'];
     25$chart1_table        = $chart1['table'];
    2726
    28         $chart1_title        = $chart['chart-title'];
    29         $chart1_img          = $chart['chart-image'];
    30         $chart1_img_position = $chart['chart-position'];
    31         $chart1_content      = $chart['chart-content'];
    32         $chart1_table        = $chart['chart-table'];
    33 }
     27$chart2_title        = $chart2['title'];
     28$chart2_img          = $chart2['image'];
     29$chart2_img_position = $chart2['position'];
     30$chart2_content      = $chart2['content'];
     31$chart2_table        = $chart2['table'];
    3432
    35 
    36 // Use get_post_meta to retrieve an existing value of chart 2 from the database.
    37 $chart2_assets       = get_post_meta( $post->ID, 'chart-2', false );
    38 $chart2_title        = '';
    39 $chart2_img          = '';
    40 $chart2_img_position = '';
    41 $chart2_content      = '';
    42 $chart2_table        = '';
    43 
    44 if ( ! empty( $chart2_assets ) ) {
    45         $chart2 = $chart2_assets[0];
    46 
    47         $chart2_title        = $chart2['chart-title'];
    48         $chart2_img          = $chart2['chart-image'];
    49         $chart2_img_position = $chart2['chart-position'];
    50         $chart2_content      = $chart2['chart-content'];
    51         $chart2_table        = $chart2['chart-table'];
    52 }
    53 
     33$chart_placeholder = plugins_url( 'images/chart-img-placeholder.jpg', dirname( __FILE__ ) );
    5434
    5535// Display the form, using the current value.
    … …  
    7353                <?php
    7454                $img = wp_get_attachment_image_src( $chart1_img, 'thumbnail' );
     55                $img = $img ? $img : array( '', 150, 100 );
    7556                ?>
    7657                <div id="field-image">
    77                         <span style="display: <?php echo $img ? 'block' : 'none'; ?>;" class="_img_remove" data-placeholder="<?php echo plugins_url( 'images/chart-img-placeholder.jpg', dirname( __FILE__ ) ); ?>" data-id="primary-chart-image">×</span>
    78                         <img class="chart_img" src="<?php echo ! empty( $img[0] ) ? esc_url( $img[0] ) : plugins_url( 'images/chart-img-placeholder.jpg', dirname( __FILE__ ) ); ?>" width="<?php echo absint( $img[1] ); ?>" height="<?php echo absint( $img[2] ); ?>" id="meta_img_1" />
     58                        <span style="display: <?php echo ! empty( $img[0] ) ? 'block' : 'none'; ?>;" class="_img_remove" data-placeholder="<?php echo esc_url( $chart_placeholder ); ?>" data-id="primary-chart-image">×</span>
     59                        <img class="chart_img" src="<?php echo ! empty( $img[0] ) ? esc_url( $img[0] ) : esc_url( $chart_placeholder ); ?>" width="<?php echo absint( $img[1] ); ?>" height="<?php echo absint( $img[2] ); ?>" id="meta_img_1" />
    7960                </div>
    8061                <div class="field-item"><input type="button" id="meta-image-button-1" class="button" value="<?php esc_html_e( 'Upload', 'productsize-chart-for-woocommerce' ); ?>" /></div>
    … …  
    8768                        <select name="image-position-1" id="image-position-1">
    8869                                <option value="left" <?php selected( $chart1_img_position, 'left' ); ?>><?php esc_html_e( 'Left', 'productsize-chart-for-woocommerce' ); ?></option>
    89                                 <option value="right" <?php selected( $chart1_img_position, 'rightt' ); ?>><?php esc_html_e( 'Right', 'productsize-chart-for-woocommerce' ); ?></option>
     70                                <option value="right" <?php selected( $chart1_img_position, 'right' ); ?>><?php esc_html_e( 'Right', 'productsize-chart-for-woocommerce' ); ?></option>
    9071                        </select>
    9172                </div>
    … …  
    121102                <div class="field-description"><?php esc_html_e( 'Add/Edit chart image below', 'productsize-chart-for-woocommerce' ); ?></div>
    122103                <div class="field-item">
    123                         <input type="hidden" name="chart-image-2" id="chart-image-2" value="<?php absint( $chart2_img ); ?>" />
     104                        <input type="hidden" name="chart-image-2" id="chart-image-2" value="<?php echo absint( $chart2_img ); ?>" />
    124105                </div>
    125106                <?php
    126107                $img = wp_get_attachment_image_src( $chart2_img, 'thumbnail' );
     108                $img = $img ? $img : array( '', 150, 100 );
    127109                ?>
    128110                <div id="field-image">
    129                         <span style="display: <?php echo $img ? 'block' : 'none'; ?>;" class="_img_remove" data-placeholder="<?php echo plugins_url( 'images/chart-img-placeholder.jpg', dirname( __FILE__ ) ); ?>" data-id="primary-chart-image">×</span>
    130                         <img class="chart_img" src="<?php echo ! empty( $img[0] ) ? esc_url( $img[0] ) : plugins_url( 'images/chart-img-placeholder.jpg', dirname( __FILE__ ) ); ?>" width="<?php echo absint( $img[1] ); ?>" height="<?php echo absint( $img[2] ); ?>" id="meta_img_2" />
     111                        <span style="display: <?php echo ! empty( $img[0] ) ? 'block' : 'none'; ?>;" class="_img_remove" data-placeholder="<?php echo esc_url( $chart_placeholder ); ?>" data-id="primary-chart-image">×</span>
     112                        <img class="chart_img" src="<?php echo ! empty( $img[0] ) ? esc_url( $img[0] ) : esc_url( $chart_placeholder ); ?>" width="<?php echo absint( $img[1] ); ?>" height="<?php echo absint( $img[2] ); ?>" id="meta_img_2" />
    131113                </div>
    132114                 <div class="field-item"><input type="button" id="meta-image-button-2" class="button" value="<?php esc_html_e( 'Upload', 'productsize-chart-for-woocommerce' ); ?>" /></div>
  • productsize-chart-for-woocommerce/tags/1.2.0/admin/includes/productsize-chart-meta-form.php

    r2595861 r3789847  
    5050                <?php  ?>
    5151                <div id="field-image">
    52                         <span style="display: <?php echo $img ? 'block' : 'none'; ?>;" class="_img_remove" data-placeholder="<?php echo plugins_url( 'images/chart-img-placeholder.jpg', dirname( __FILE__ ) ); ?>" data-id="primary-chart-image">×</span>
    53                         <img class="chart_img" src="<?php echo ! empty( $img[0] ) ? esc_url( $img[0] ) : plugins_url( 'images/chart-img-placeholder.jpg', dirname( __FILE__ ) ); ?>" width="<?php echo absint( $img[1] ); ?>" height="<?php echo absint( $img[2] ); ?>"  id="meta_img" />
     52                        <span style="display: <?php echo ! empty( $img[0] ) ? 'block' : 'none'; ?>;" class="_img_remove" data-placeholder="<?php echo esc_url( plugins_url( 'images/chart-img-placeholder.jpg', dirname( __FILE__ ) ) ); ?>" data-id="primary-chart-image">×</span>
     53                        <img class="chart_img" src="<?php echo ! empty( $img[0] ) ? esc_url( $img[0] ) : esc_url( plugins_url( 'images/chart-img-placeholder.jpg', dirname( __FILE__ ) ) ); ?>" width="<?php echo absint( $img[1] ); ?>" height="<?php echo absint( $img[2] ); ?>"  id="meta_img" />
    5454                </div>
    5555                <div class="field-item"><input type="button" id="meta-image-button" class="button" value="<?php esc_html_e( 'Upload', 'productsize-chart-for-woocommerce' ); ?>" /></div>
    … …  
    110110        </div>
    111111        <div style="clear:both"></div>
    112         <div id="field" class="tab-or-modal" <?php echo $chart_position == 'tab' ? "style='display:none;'" : ''; ?>>
     112        <div id="field" class="tab-or-modal" <?php echo 'tab' === $chart_position ? 'style="display:none;"' : ''; ?>>
    113113                <div class="field-title"><h4><?php esc_html_e( 'Chart Popup Button Position', 'productsize-chart-for-woocommerce' ); ?></h4></div>
    114114                <div class="field-description"><?php esc_html_e( 'Select where the pop up button displays', 'productsize-chart-for-woocommerce' ); ?></div>
  • productsize-chart-for-woocommerce/tags/1.2.0/admin/includes/productsize-chart-select-chart-form.php

    r2545262 r3789847  
    3939$posts_array = get_posts( $args );
    4040if ( ! is_array( $posts_array ) || sizeof( $posts_array ) == 0 ) {
    41         printf( __( 'No charts found.click <a href="%s">here</a> to create you first chart', 'productsize-chart-for-woocommerce' ), admin_url( 'edit.php?post_type=chart' ) );
     41        echo wp_kses_post(
     42                sprintf(
     43                        /* translators: %s: URL of the charts overview. */
     44                        __( 'No charts found. Click <a href="%s">here</a> to create your first chart.', 'productsize-chart-for-woocommerce' ),
     45                        esc_url( admin_url( 'edit.php?post_type=chart' ) )
     46                )
     47        );
    4248        return;
    4349}
  • productsize-chart-for-woocommerce/tags/1.2.0/admin/includes/productsize-chart-settings-form.php

    r2545262 r3789847  
    2020<div class="wrap ajax_cart">
    2121        <h1><?php esc_html_e( 'Size Chart Settings', 'productsize-chart-for-woocommerce' ); ?></h1>
    22         <form method="post" action="<?php admin_url( 'admin.php?page=productsize_chart' ); ?>" enctype="multipart/form-data">
     22        <form method="post" action="<?php echo esc_url( admin_url( 'edit.php?post_type=chart&page=productsize_chart' ) ); ?>" enctype="multipart/form-data">
    2323                <h2 class="nav-tab-wrapper woo-nav-tab-wrapper">
    24                         <a href="<?php echo admin_url( 'admin.php?page=productsize_chart&tab=pop-up' ); ?>" class="nav-tab nav-tab-active"><?php esc_html_e( 'Default Settings', 'productsize-chart-for-woocommerce' ); ?></a>
     24                        <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=chart&page=productsize_chart' ) ); ?>" class="nav-tab nav-tab-active"><?php esc_html_e( 'Default Settings', 'productsize-chart-for-woocommerce' ); ?></a>
    2525                </h2>
    2626                <table class="form-table">
    … …  
    2929                        wp_nonce_field( 'productsize_chart_page' );
    3030
    31                         if ( $pagenow == 'edit.php' && $_GET['page'] == 'productsize_chart' ) {
     31                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check of the current admin page.
     32                        if ( 'edit.php' === $pagenow && isset( $_GET['page'] ) && 'productsize_chart' === sanitize_key( wp_unslash( $_GET['page'] ) ) ) {
    3233                                ?>
    3334                               
    … …  
    214215                                        <td>
    215216                                                <input type="text" name="productsize-chart-button-label"  value="<?php echo esc_attr( $this->productsize_chart_settings['productsize-chart-button-label'] ); ?>"/>
     217                                        </td>
     218                                </tr>
     219
     220                                <tr>
     221                                        <th><?php esc_html_e( 'Link to Sizegram', 'productsize-chart-for-woocommerce' ); ?></th>
     222                                        <td>
     223                                                <label>
     224                                                        <input type="checkbox" name="productsize-chart-show-credit" value="1" <?php checked( 1, (int) $this->productsize_chart_settings['productsize-chart-show-credit'] ); ?> />
     225                                                        <?php esc_html_e( 'Yes, support Sizegram with a small "Size chart by Sizegram" link below the size chart', 'productsize-chart-for-woocommerce' ); ?>
     226                                                </label>
     227                                                <p class="description"><?php esc_html_e( 'This plugin is free and we do not ask for a subscription. If it helps your store, please consider showing this small link to Sizegram.com instead. It is optional, off by default and only appears together with a size chart. Thank you for your support!', 'productsize-chart-for-woocommerce' ); ?></p>
    216228                                        </td>
    217229                                </tr>
  • productsize-chart-for-woocommerce/tags/1.2.0/includes/class-productsize-chart.php

    r2545262 r3789847  
    5757
    5858                $this->plugin_name = 'productsize-chart-for-woocommerce';
    59                 $this->version = '1.1.0';
     59                $this->version = PRODUCTSIZE_CHART_VERSION;
    6060
    6161                $this->load_dependencies();
    … …  
    121121         */
    122122        private function set_locale() {
    123                 $plugin_i18n = new productsize_chart_i18n();
    124                 $plugin_i18n->set_domain( $this->get_plugin_name());
    125                 $plugin_i18n->load_plugin_textdomain();
     123                // Translations are loaded automatically by WordPress for plugins hosted on WordPress.org
     124                // (translate.wordpress.org), so no load_plugin_textdomain() call is needed.
    126125        }
    127126
    … …  
    163162                $this->loader->add_filter( 'woocommerce_product_tabs', $plugin_public, 'productsize_chart_new_product_tab' );
    164163                $this->loader->add_action( 'woocommerce_before_single_product', $plugin_public, 'productsize_chart_check_popup_button_position' );
    165                 $this->loader->add_action( 'wp_head', $plugin_public, 'productsize_chart_custom_style' );
    166164
    167165        }
  • productsize-chart-for-woocommerce/tags/1.2.0/productsize-chart-for-woocommerce.php

    r3070321 r3789847  
    22/**
    33 * @wordpress-plugin
    4  * Plugin Name:       Product Size Chart for Woocommerce
    5  * Description:       This plugin allow you to use size charts to products on woocommerce.
    6  * Version:           1.1.4
     4 * Plugin Name:       Product Size Chart & Size Guide for WooCommerce
     5 * Description:       Add size charts and size guides to your WooCommerce products, as a pop up or as a product tab.
     6 * Version:           1.2.0
     7 * Requires at least: 6.5
     8 * Requires PHP:      7.4
     9 * Requires Plugins:  woocommerce
    710 * Author:            knaldi2020
    811 * Author URI:        https://sizegram.com/
    … …  
    1114 * Text Domain:       productsize-chart-for-woocommerce
    1215 * Domain Path:       /languages
     16 * WC tested up to:   11.1
    1317 */
    1418
    … …  
    1721        die;
    1822}
     23
     24/**
     25 * Current plugin version. Keep in sync with the "Version" header above.
     26 */
     27define( 'PRODUCTSIZE_CHART_VERSION', '1.2.0' );
    1928
    2029/**
    … …  
    5261function productsize_chart_for_woocommerce_missing_wc_notice() {
    5362        /* translators: 1. URL link. */
    54         echo '<div class="error"><p><strong>' . sprintf( esc_html__( 'Product Size Chart for Woocommerce requires WooCommerce to be installed and active. You can download %s here.', 'productsize-chart-for-woocommerce' ), '<a href="https://woocommerce.com/" target="_blank">WooCommerce</a>' ) . '</strong></p></div>';
     63        echo '<div class="error"><p><strong>' . wp_kses_post(
     64                sprintf(
     65                        /* translators: 1. URL link. */
     66                        esc_html__( 'Product Size Chart & Size Guide for WooCommerce requires WooCommerce to be installed and active. You can download %s here.', 'productsize-chart-for-woocommerce' ),
     67                        '<a href="https://woocommerce.com/" target="_blank" rel="noopener">WooCommerce</a>'
     68                )
     69        ) . '</strong></p></div>';
    5570}
     71
     72/**
     73 * Declare compatibility with WooCommerce features.
     74 *
     75 * The plugin does not read or write orders and does not touch the cart or checkout.
     76 *
     77 * @since 1.1.5
     78 */
     79function productsize_chart_declare_wc_compatibility() {
     80        if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
     81                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
     82                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true );
     83        }
     84}
     85add_action( 'before_woocommerce_init', 'productsize_chart_declare_wc_compatibility' );
    5686
    5787add_action( 'plugins_loaded', 'productsize_chart_for_woocommerce_init' );
  • productsize-chart-for-woocommerce/tags/1.2.0/public/class-productsize-chart-public.php

    r2547692 r3789847  
    33/**
    44 * The public-facing functionality of the plugin.
    5  *
    6  * Defines the plugin name, version, and two examples hooks for how to
    7  * enqueue the admin-specific stylesheet and JavaScript.
    85 *
    96 * @package    productsize-chart-for-woocommerce
    … …  
    118 * @author     Nabaraj Chapagain <nabarajc6@gmail.com>
    129 */
     10
     11if ( ! defined( 'ABSPATH' ) ) {
     12        exit; // exit if accessed directly.
     13}
     14
     15/**
     16 * Shows the size chart on the single product page (as a tab or as a modal pop up).
     17 */
    1318class productsize_chart_Public {
    1419
    … …  
    3237
    3338        /**
    34          * The elements or assets of plugin.
     39         * The elements or assets of the chart that is being shown.
    3540         *
    3641         * @since    1.0.0
    3742         * @access   private
    38          * @var      array    $assets    The assets/settings of plugin like color,content etc.
     43         * @var      array    $assets    The assets/settings of the chart like color, content etc.
    3944         */
    4045        private $assets;
    4146
    4247        /**
    43          * The default elements or assets of plugin.
     48         * The default settings of the plugin.
    4449         *
    4550         * @since    1.0.0
    4651         * @access   private
    47          * @var      array    $default_assets    The default assets/settings of plugin like color,content etc.
     52         * @var      array    $default_assets    The default settings like color, button label etc.
    4853         */
    4954        private $default_assets;
     55
     56        /**
     57         * Chart ID per product, so the lookup runs once per request.
     58         *
     59         * @since    1.1.5
     60         * @access   private
     61         * @var      array
     62         */
     63        private $chart_id_cache = array();
    5064
    5165        /**
    … …  
    6074                $this->plugin_name    = $plugin_name;
    6175                $this->version        = $version;
    62                 $this->default_assets = get_option( 'productsize_chart_settings' );
    63 
    64         }
    65 
    66         /**
    67          * convert hex to rgba
    68          *
    69          * @since    1.0.0
    70          * @param      string $color      color code for e.g. #000000
    71          * @param      string $opacity    opacity for rgba
     76                $saved                = get_option( 'productsize_chart_settings', array() );
     77                $this->default_assets = wp_parse_args( is_array( $saved ) ? $saved : array(), productsize_chart_Admin::default_settings() );
     78
     79        }
     80
     81        /**
     82         * Convert a hex colour to rgb / rgba.
     83         *
     84         * @since    1.0.0
     85         * @param    string      $color   Hex colour.
     86         * @param    float|false $opacity Opacity between 0 and 1.
     87         * @return   string
    7288         */
    7389        public function productsize_chart_hex2rgba( $color, $opacity = false ) {
     90
    7491                $default = 'rgb(0,0,0)';
    75                 // Return default if no color provided
     92
     93                // Return default if no color provided.
    7694                if ( empty( $color ) ) {
    7795                        return $default;
    7896                }
    79                 // Sanitize $color if "#" is provided
    80                 if ( $color[0] == '#' ) {
     97
     98                // Sanitize $color if "#" is provided.
     99                if ( '#' === $color[0] ) {
    81100                        $color = substr( $color, 1 );
    82101                }
    83102
    84                 // Check if color has 6 or 3 characters and get values
    85                 if ( strlen( $color ) == 6 ) {
     103                // Check if color has 6 or 3 characters and get values.
     104                if ( 6 === strlen( $color ) ) {
    86105                        $hex = array( $color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5] );
    87                 } elseif ( strlen( $color ) == 3 ) {
     106                } elseif ( 3 === strlen( $color ) ) {
    88107                        $hex = array( $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] );
    89108                } else {
    … …  
    91110                }
    92111
    93                 // Convert hexadec to rgb
     112                // Convert hexadec to rgb.
    94113                $rgb = array_map( 'hexdec', $hex );
    95114
    96                 // Check if opacity is set(rgba or rgb)
     115                // Check if opacity is set (rgba or rgb).
    97116                if ( $opacity ) {
    98117                        if ( abs( $opacity ) > 1 ) {
    99118                                $opacity = 1.0;
    100119                        }
    101                         $output = 'rgba(' . implode( ',', $rgb ) . ',' . $opacity . ')';
     120                        $output = 'rgba(' . implode( ',', $rgb ) . ',' . (float) $opacity . ')';
    102121                } else {
    103122                        $output = 'rgb(' . implode( ',', $rgb ) . ')';
    104123                }
    105                 // Return rgb(a) color string
     124
    106125                return $output;
    107126        }
    108127
    109128        /**
    110          * convert hex to rgba
    111          *
    112          * @since    1.0.0
    113          * @param      string $chart_content    display chart details with table
     129         * Return a safe heading tag.
     130         *
     131         * @since    1.1.5
     132         * @param    string $tag     Tag from the settings.
     133         * @param    string $default Fallback tag.
     134         * @return   string
     135         */
     136        private function heading_tag( $tag, $default ) {
     137                $tag = strtolower( (string) $tag );
     138                return in_array( $tag, array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), true ) ? $tag : $default;
     139        }
     140
     141        /**
     142         * Display a chart table.
     143         *
     144         * @since    1.0.0
     145         * @param    string $chart_content JSON list of rows.
    114146         */
    115147        public function productsize_chart_display_table( $chart_content ) {
    116                 $chart = json_decode( $chart_content );
    117                 if ( sizeof( $chart ) > 1 ) {
    118                         echo "<table id='size-chart'>";
    119                         $first = 0;
    120                         foreach ( $chart as $chart_details ) {
    121 
    122                                 echo '<tr>';
    123                                 for ( $i = 0; $i < count( $chart_details ); $i++ ) {
    124 
    125                                         echo ( $first == 0 ) ? '<th>' . wp_kses_post( $chart_details[ $i ] ) . '</th>' : '<td>' . wp_kses_post( $chart_details[ $i ] ) . '</td>';
    126                                 }
    127                                 echo '</tr>';
    128                                 $first++;
    129                         }
    130                         echo '</table>';
    131 
    132                 }
    133 
    134         }
    135 
    136         /**
    137          * chart assets
    138          *
    139          * @since    1.0.0
    140          */
    141 
     148
     149                $chart = json_decode( (string) $chart_content );
     150                if ( ! is_array( $chart ) || count( $chart ) < 2 ) {
     151                        return;
     152                }
     153
     154                echo "<table id='size-chart'>";
     155                $first = 0;
     156                foreach ( $chart as $chart_details ) {
     157                        if ( ! is_array( $chart_details ) ) {
     158                                continue;
     159                        }
     160                        echo '<tr>';
     161                        foreach ( $chart_details as $cell ) {
     162                                $cell = wp_kses_post( (string) $cell );
     163                                echo ( 0 === $first ) ? '<th>' . $cell . '</th>' : '<td>' . $cell . '</td>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped with wp_kses_post() above.
     164                        }
     165                        echo '</tr>';
     166                        ++$first;
     167                }
     168                echo '</table>';
     169
     170        }
     171
     172        /**
     173         * Chart assets.
     174         *
     175         * @since    1.0.0
     176         * @param    int $chart_id Chart post ID.
     177         * @return   array Empty when there is no chart.
     178         */
    142179        public function productsize_chart_assets( $chart_id ) {
     180
     181                if ( ! $chart_id ) {
     182                        return array();
     183                }
     184
     185                $chart_1 = get_post_meta( $chart_id, 'chart-1', true );
     186                $chart_2 = get_post_meta( $chart_id, 'chart-2', true );
     187
    143188                $this->assets = array(
    144189                        'label'       => get_post_meta( $chart_id, 'label', true ),
    145190                        'chart'       => $chart_id,
    146191                        'position'    => get_post_meta( $chart_id, 'position', true ),
    147                         'content'     => get_post_meta( $chart_id, 'chart-content', true ),
    148192                        'text-color'  => get_post_meta( $chart_id, 'text-color', true ),
    149193                        'title-color' => get_post_meta( $chart_id, 'title-color', true ),
    … …  
    152196                        'padding'     => get_post_meta( $chart_id, 'chart-padding', true ),
    153197                        'chart-table' => get_post_meta( $chart_id, 'chart-table', true ),
    154                         'chart-1'     => get_post_meta( $chart_id, 'chart-1', false ),
    155                         'chart-2'     => get_post_meta( $chart_id, 'chart-2', false ),
     198                        'chart-1'     => $chart_1 ? productsize_chart_Admin::normalize_extra_chart( $chart_1, 1 ) : array(),
     199                        'chart-2'     => $chart_2 ? productsize_chart_Admin::normalize_extra_chart( $chart_2, 2 ) : array(),
    156200                );
    157201
    158                 $but_pos = get_post_meta( $chart_id, 'position', true );
    159                 if ( $but_pos && $but_pos == 'popup' ) {
    160                         $button_position = get_post_meta( $chart_id, 'button-position', true );
    161                         $this->assets    = array_merge( array( 'button-position' => $button_position ), $this->assets );
     202                if ( 'popup' === $this->assets['position'] ) {
     203                        $this->assets = array_merge( array( 'button-position' => get_post_meta( $chart_id, 'button-position', true ) ), $this->assets );
    162204                }
    163205
    164206                return $this->assets;
    165 
    166         }
    167 
    168         /**
    169          * Check if product belongs to a category that has a chart assigned
    170          *
    171          * @since    1.0.0
     207        }
     208
     209        /**
     210         * Find the chart that is assigned to one of the categories of a product.
     211         *
     212         * @since    1.0.0
     213         * @param    int $id Product ID.
     214         * @return   int|string Chart ID or empty string.
    172215         */
    173216        public function productsize_chart_id_by_categories( $id ) {
    174217
    175218                $chart_terms = wp_get_post_terms( $id, 'product_cat', array( 'fields' => 'ids' ) );
    176                 $productsize_chart_category_args = array(
    177                         'post_type'      => 'chart',
    178                         'posts_per_page' => '-1',
    179                         'posts_status'   => 'publish',
    180                         'orderby'        => 'ID',
    181                         'order'          => 'DESC',
     219                if ( is_wp_error( $chart_terms ) || empty( $chart_terms ) ) {
     220                        return '';
     221                }
     222                $chart_terms = array_map( 'absint', $chart_terms );
     223
     224                $charts = get_posts(
     225                        array(
     226                                'post_type'      => 'chart',
     227                                'posts_per_page' => -1,
     228                                'post_status'    => 'publish',
     229                                'orderby'        => 'ID',
     230                                'order'          => 'DESC',
     231                                'fields'         => 'ids',
     232                        )
    182233                );
    183234
    184                 $productsize_chart_array = get_posts( $productsize_chart_category_args );
    185                 $arr                     = array();
    186                 $chart_id                = '';
    187                 if ( sizeof( $productsize_chart_array ) > 0 ) :
    188                         foreach ( $productsize_chart_array as $new_chart_details ) {
    189                                 $chart_categories = get_post_meta( $new_chart_details->ID, 'chart-categories', true );
    190                                 if ( $chart_categories ) :
    191                                         foreach ( $chart_categories as $key => $value ) {
    192                                                 $arr[ $key ] = $value;
    193                                         }
    194                                 endif;
    195                                
    196                                 if ( sizeof( $chart_terms ) > 0 && sizeof( $arr ) > 0 ) :
    197                                         if ( array_intersect( $arr, $chart_terms ) ) {
    198                                                 $chart_id = $new_chart_details->ID;
    199 
    200                                         }
    201                                         if ( $chart_id ) {
    202                                                 break;
    203                                         }
    204                                 endif;
    205                         }
    206                 endif;
    207 
    208                 return $chart_id;
    209         }
    210 
    211         /**
    212          * check product chart avialable or not
    213          *
    214          * @since    1.0.0
    215          */
    216 
     235                foreach ( $charts as $chart_id ) {
     236                        $chart_categories = get_post_meta( $chart_id, 'chart-categories', true );
     237                        if ( is_array( $chart_categories ) && array_intersect( array_map( 'absint', $chart_categories ), $chart_terms ) ) {
     238                                return $chart_id;
     239                        }
     240                }
     241
     242                return '';
     243        }
     244
     245        /**
     246         * The chart that was selected directly on the product.
     247         *
     248         * @since    1.0.0
     249         * @param    int $id Product ID.
     250         * @return   mixed
     251         */
    217252        public function productsize_chart_check( $id ) {
     253
    218254                $chart_id = get_post_meta( $id, 'prod-chart', true );
    219255                if ( $chart_id ) {
    220256                        return $chart_id;
    221257                }
    222 
    223         }
    224 
    225 
    226         /**
    227          * check product chart avialable or not
    228          *
    229          * @since    1.0.0
    230          */
    231 
     258        }
     259
     260        /**
     261         * Chart ID for a product: the chart selected on the product, else the chart of its category.
     262         *
     263         * @since    1.0.0
     264         * @param    int $id Product ID.
     265         * @return   int|string
     266         */
    232267        public function productsize_chart_id( $id ) {
    233268
    234                 if ( $this->productsize_chart_check( $id ) ) :
     269                if ( ! isset( $this->chart_id_cache[ $id ] ) ) {
    235270                        $chart_id = $this->productsize_chart_check( $id );
    236                 else :
    237                         $chart_id = $this->productsize_chart_id_by_categories( $id );
    238                 endif;
    239 
    240                 return $chart_id;
    241 
    242         }
    243 
    244 
    245         /**
    246          * check popu up button position
    247          *
    248          * @since    1.0.0
    249          */
    250 
     271                        if ( ! $chart_id ) {
     272                                $chart_id = $this->productsize_chart_id_by_categories( $id );
     273                        }
     274                        $this->chart_id_cache[ $id ] = $chart_id;
     275                }
     276
     277                return $this->chart_id_cache[ $id ];
     278        }
     279
     280        /**
     281         * Chart ID and assets of the product that is currently shown.
     282         *
     283         * @since    1.1.5
     284         * @return   array array( chart ID, assets )
     285         */
     286        private function current_chart() {
     287
     288                $post = get_post();
     289                if ( ! $post ) {
     290                        return array( 0, array() );
     291                }
     292
     293                $chart_id = $this->productsize_chart_id( $post->ID );
     294
     295                return array( $chart_id, $this->productsize_chart_assets( $chart_id ) );
     296        }
     297
     298        /**
     299         * Hook the pop up button on the position that is set on the chart.
     300         *
     301         * @since    1.0.0
     302         */
    251303        public function productsize_chart_check_popup_button_position() {
    252                 global $post;
    253                 $chart_id = $this->productsize_chart_id( $post->ID );
    254                 $assets   = $this->productsize_chart_assets( $chart_id );
    255 
    256                 if ( ! is_array( $assets ) || ! array_key_exists( 'button-position', $assets ) ) {
     304
     305                list( , $assets ) = $this->current_chart();
     306                if ( ! array_key_exists( 'button-position', $assets ) ) {
    257307                        return;
    258308                }
    … …  
    260310                $position = $assets['button-position'];
    261311                $priority = 31;
    262 
    263                 if ( 'before-summary-text' == $position ) {
     312                if ( 'before-summary-text' === $position ) {
    264313                        $priority = 11;
    265                 }elseif ( 'before-add-to-cart' == $position ) {
     314                } elseif ( 'before-add-to-cart' === $position ) {
    266315                        $priority = 29;
    267                 }elseif ( 'after-product-meta' == $position ) {
     316                } elseif ( 'after-product-meta' === $position ) {
    268317                        $priority = 41;
    269318                }
    … …  
    271320                $hook     = apply_filters( 'productsize_chart_button_hook', 'woocommerce_single_product_summary', $assets );
    272321                $priority = apply_filters( 'productsize_chart_button_priority', $priority, $assets );
     322
    273323                add_action( $hook, array( $this, 'productsize_chart_button' ), $priority );
    274 
    275         }
    276 
    277 
    278         /**
    279          * Register the stylesheets for the public-facing side of the site.
    280          *
    281          * @since    1.0.0
    282          */
    283 
     324        }
     325
     326        /**
     327         * Add the chart as a product tab.
     328         *
     329         * @since    1.0.0
     330         * @param    array $tabs Product tabs.
     331         * @return   array
     332         */
    284333        public function productsize_chart_new_product_tab( $tabs ) {
    285                 global $post;
    286 
    287                 $chart_id = $this->productsize_chart_id( $post->ID );
    288                 $assets   = $this->productsize_chart_assets( $chart_id );
    289 
    290                 if ( ! is_array( $assets ) || ! array_key_exists( 'chart', $assets ) ) {
     334
     335                list( , $assets ) = $this->current_chart();
     336                if ( ! array_key_exists( 'chart', $assets ) ) {
    291337                        return $tabs;
    292338                }
    293339
    294                 $default_assets = $this->default_assets;
    295 
    296                 if ( 'tab' == $assets['position'] ) {
     340                if ( 'tab' === $assets['position'] ) {
    297341                        $tabs['custom_tab'] = array(
    298                                 'title'    => $default_assets['productsize-chart-button-label'],
     342                                'title'    => $this->default_assets['productsize-chart-button-label'],
    299343                                'priority' => 50,
    300344                                'callback' => array( $this, 'productsize_chart_new_product_tab_content' ),
    301345                        );
    302 
    303346                }
    304347
    305348                return $tabs;
    306 
    307         }
    308 
    309         /**
    310          * Register the stylesheets for the public-facing side of the site.
    311          *
    312          * @since    1.0.0
    313          */
    314 
     349        }
     350
     351        /**
     352         * Tab content.
     353         *
     354         * @since    1.0.0
     355         */
    315356        public function productsize_chart_new_product_tab_content() {
    316                 global $post;
    317 
    318                 $chart_id = $this->productsize_chart_id( $post->ID );
    319                 $assets   = $this->productsize_chart_assets( $chart_id );
    320 
    321                 if ( ! is_array( $assets ) || ! array_key_exists( 'chart', $assets ) ) {
     357
     358                list( $chart_id, $assets ) = $this->current_chart();
     359                if ( ! array_key_exists( 'chart', $assets ) ) {
    322360                        return;
    323361                }
    … …  
    327365
    328366        /**
    329          * hook to display chart button after add to cart button for modal
    330          *
    331          * @since    1.0.0
    332          */
    333 
     367         * Pop up button and modal.
     368         *
     369         * @since    1.0.0
     370         */
    334371        public function productsize_chart_button() {
    335                 global $post;
    336 
    337                 $chart_id = $this->productsize_chart_id( $post->ID );
    338                 $assets   = $this->productsize_chart_assets( $chart_id );
    339 
    340                 if ( ! is_array( $assets ) || ! array_key_exists( 'position', $assets ) ) {
     372
     373                list( $chart_id, $assets ) = $this->current_chart();
     374                if ( ! array_key_exists( 'position', $assets ) || 'popup' !== $assets['position'] ) {
    341375                        return;
    342376                }
    343377
    344                 $class = 'chart-button';
     378                $default_assets = $this->default_assets;
     379                $class          = 'chart-button';
    345380                if ( ! empty( $default_assets['productsize-chart-button-class'] ) ) {
    346381                        $class .= ' ' . $default_assets['productsize-chart-button-class'];
    347382                }
    348 
    349                 if ( $assets['position'] == 'popup' ) {
    350                         $default_assets = $this->default_assets;
    351                         ?>
    352                         <div class="button-wrapper"><a href="#modal" class="<?php echo esc_attr( $class );?>" id="chart-button"><?php echo esc_html( $default_assets['productsize-chart-button-label'] ); ?></a></div>
    353                         <div class="remodal" data-remodal-id="modal" role="dialog" aria-labelledby="modal1Title" aria-describedby="modal1Desc">
    354                                 <button data-remodal-action="close" class="remodal-close" aria-label="Close"></button>
    355                                 <div>
    356                                         <?php include 'includes/productsize-chart-contents.php'; ?>
    357                                 </div>
     383                ?>
     384                <div class="button-wrapper"><a href="#modal" class="<?php echo esc_attr( $class ); ?>" id="chart-button"><?php echo esc_html( $default_assets['productsize-chart-button-label'] ); ?></a></div>
     385                <div class="remodal" data-remodal-id="modal" role="dialog" aria-labelledby="modal1Title" aria-describedby="modal1Desc">
     386                        <button data-remodal-action="close" class="remodal-close" aria-label="<?php esc_attr_e( 'Close', 'productsize-chart-for-woocommerce' ); ?>"></button>
     387                        <div>
     388                                <?php include 'includes/productsize-chart-contents.php'; ?>
    358389                        </div>
    359                         <?php
    360                 }
    361 
    362         }
    363 
    364 
     390                </div>
     391                <?php
     392        }
     393
     394        /**
     395         * Build the CSS for the chart of the current product.
     396         *
     397         * @since    1.0.0
     398         * @return   string Empty when the product has no chart.
     399         */
    365400        public function productsize_chart_custom_style() {
    366                 global $post;
    367 
    368                 $chart_id = $this->productsize_chart_id( $post->ID );
    369                 $assets   = $this->productsize_chart_assets( $chart_id );
     401
     402                list( , $assets ) = $this->current_chart();
     403                if ( ! array_key_exists( 'chart', $assets ) ) {
     404                        return '';
     405                }
    370406
    371407                $default_assets  = $this->default_assets;
    … …  
    375411                $overlay         = ! empty( $assets['overlay'] ) ? $assets['overlay'] : $default_assets['productsize-chart-overlay-color'];
    376412                $opacity         = $default_assets['productsize-chart-overlay-opacity'];
    377                 $padding         = ! empty( $assets['padding'] ) ? $assets['padding'] . 'px' : '35px';
    378                 $overlay_bg      = ! empty( $assets['overlay'] ) ? $this->productsize_chart_hex2rgba( $overlay, $opacity ) :
    379                 $this->productsize_chart_hex2rgba( $overlay, $opacity );
     413                $padding         = ! empty( $assets['padding'] ) ? absint( $assets['padding'] ) . 'px' : '35px';
     414                $overlay_bg      = $this->productsize_chart_hex2rgba( $overlay, $opacity );
    380415                $button_bg       = $default_assets['productsize-chart-button-bg-color'];
    381416                $button_color    = $default_assets['productsize-chart-button-text-color'];
    382417                $button_hover_bg = $default_assets['productsize-chart-button-hover-bg'];
    383418
    384                 ?>
    385                 <style type="text/css">
    386                         #size-chart {clear:both; margin:10px 0; width:100%}#size-chart tr th{font-weight:bold;}
    387                         #size-chart tr td,#size-chart tr th{color:<?php echo esc_attr($color); ?>;
    388                         padding:8px; text-align:left;}
    389                         .remodal p{color:<?php echo esc_attr($color); ?>; text-align:justify;}
    390                         #modal1Title{color:<?php echo esc_attr($title_color); ?>; margin-bottom:15px; font-size:25px; text-align:left}
    391 
    392                         <?php if ( $table_style == 'style-1' ) { ?>
    393                                 #size-chart tr:nth-child(odd){background:#ebe9eb;}
    394                         <?php }else{ ?>
    395                                 #size-chart tr th{background:#000000; color:#ffffff; text-align:center;}
    396                                 #size-chart tr td,#size-chart tr th{border:1px solid #CCCCCC; text-align:center;}
    397                         <?php } ?>
    398                        
    399                         .remodal-overlay {background:<?php echo esc_attr($overlay_bg); ?> !important; z-index:9999;}
    400                         .remodal{padding:<?php echo esc_attr($padding); ?>;}
    401                         .remodal .remodal-close{top:<?php echo esc_attr($padding); ?>;right:<?php echo esc_attr($padding); ?>;}
    402                         .button-wrapper{margin:7px 0;}
    403                         #chart-button{background:<?php echo $button_bg; ?>; color:<?php echo esc_attr($button_color); ?>; padding:7px 10px;font-weight: 700;
    404                         border-radius: 3px; -webkit-border-radius: 3px;-moz-border-radius: 3px; text-decoration:none; }
    405                         #chart-button:hover{background:<?php echo esc_attr($button_hover_bg); ?>;  }
    406                 </style>   
    407                 <?php
    408         }
    409 
     419                $css  = '#size-chart {clear:both; margin:10px 0; width:100%}#size-chart tr th{font-weight:bold;}';
     420                $css .= '#size-chart tr td,#size-chart tr th{color:' . $color . '; padding:8px; text-align:left;}';
     421                $css .= '.remodal p{color:' . $color . '; text-align:justify;}';
     422                $css .= '#modal1Title{color:' . $title_color . '; margin-bottom:15px; font-size:25px; text-align:left}';
     423                if ( 'style-1' === $table_style ) {
     424                        $css .= '#size-chart tr:nth-child(odd){background:#ebe9eb;}';
     425                } else {
     426                        $css .= '#size-chart tr th{background:#000000; color:#ffffff; text-align:center;}';
     427                        $css .= '#size-chart tr td,#size-chart tr th{border:1px solid #CCCCCC; text-align:center;}';
     428                }
     429                $css .= '.remodal-overlay {background:' . $overlay_bg . ' !important; z-index:9999;}';
     430                $css .= '.remodal{padding:' . $padding . ';}';
     431                $css .= '.remodal .remodal-close{top:' . $padding . ';right:' . $padding . ';}';
     432                $css .= '.button-wrapper{margin:7px 0;}';
     433                $css .= '#chart-button{background:' . $button_bg . '; color:' . $button_color . '; padding:7px 10px;font-weight: 700; border-radius: 3px; -webkit-border-radius: 3px;-moz-border-radius: 3px; text-decoration:none; }';
     434                $css .= '#chart-button:hover{background:' . $button_hover_bg . ';}';
     435                if ( 1 === (int) $default_assets['productsize-chart-show-credit'] ) {
     436                        $css .= '.productsize-chart-credit{margin:14px 0 0;font-size:11px;line-height:1.4;opacity:.65;text-align:right;}';
     437                        $css .= '.productsize-chart-credit:hover{opacity:1;}';
     438                        $css .= '.productsize-chart-credit a{color:inherit;text-decoration:underline;}';
     439                }
     440
     441                // Every value above comes from validated settings; strip anything that could break out of the style element.
     442                return wp_strip_all_tags( $css );
     443        }
    410444
    411445        /**
    … …  
    419453                        wp_enqueue_style( $this->plugin_name . '-jquery-modal', plugin_dir_url( __FILE__ ) . 'css/remodal.css', array(), $this->version, 'all' );
    420454                        wp_enqueue_style( $this->plugin_name . '-jquery-modal-default-theme', plugin_dir_url( __FILE__ ) . 'css/remodal-default-theme.css', array(), $this->version, 'all' );
     455
     456                        $css = $this->productsize_chart_custom_style();
     457                        if ( '' !== $css ) {
     458                                wp_add_inline_style( $this->plugin_name . '-jquery-modal-default-theme', $css );
     459                        }
    421460                }
    422461
  • productsize-chart-for-woocommerce/tags/1.2.0/public/includes/productsize-chart-contents.php

    r2545262 r3789847  
    11<?php
    2  /**
    3   * The public-facing functionality of the plugin.
    4   *
    5   * @package    productsize-chart-for-woocommerce
    6   * @subpackage productsize-chart-for-woocommerce/public/includes
    7   * @author     Nabaraj Chapagain <nabarajc6@gmail.com>
    8   */
     2/**
     3 * The chart that is shown on the product page (in the tab or in the modal).
     4 *
     5 * Included from productsize_chart_Public, so $this, $chart_id and $assets are available.
     6 *
     7 * @package    productsize-chart-for-woocommerce
     8 * @subpackage productsize-chart-for-woocommerce/public/includes
     9 * @author     Nabaraj Chapagain <nabarajc6@gmail.com>
     10 */
    911
    1012if ( ! defined( 'ABSPATH' ) ) {
    11         exit; // exit if accessed directly
     13        exit; // exit if accessed directly.
    1214}
    1315
    14 $title_wrapper           = $this->default_assets['productsize-chart-title'];
    15 $title                   = ! empty( $title_wrapper ) ? $title_wrapper : 'h2';
    16 $enable_additional_chart = $this->default_assets['productsize-chart-enable-additional-chart'];
     16$title_tag               = $this->heading_tag( $this->default_assets['productsize-chart-title'], 'h2' );
     17$enable_additional_chart = 1 === (int) $this->default_assets['productsize-chart-enable-additional-chart'];
     18$chart_post              = get_post( $chart_id );
    1719
    18 printf( '<%1$s id="modal1Title">%2$s</%3$s>', $title, $assets['label'], $title );
     20if ( ! $chart_post ) {
     21        return;
     22}
    1923
    20 $post_data = get_post( $chart_id );
     24printf( '<%1$s id="modal1Title">%2$s</%1$s>', esc_attr( $title_tag ), esc_html( $assets['label'] ) );
    2125
    22 $pimg = get_post_meta( $post_data->ID, 'primary-chart-image', true );
    23 if ( $pimg ) :
    24         $position = get_post_meta( $post_data->ID, 'primary-image-position', true );
    25         $pimg     = wp_get_attachment_image_src( $pimg, 'full' );
     26// Primary chart image.
     27$primary_image = absint( get_post_meta( $chart_post->ID, 'primary-chart-image', true ) );
     28if ( $primary_image ) {
     29        $image_position = 'right' === get_post_meta( $chart_post->ID, 'primary-image-position', true ) ? 'right' : 'left';
     30        $image_html     = wp_get_attachment_image( $primary_image, 'full', false, array( 'alt' => $assets['label'] ? $assets['label'] : $chart_post->post_title ) );
     31        if ( $image_html ) {
     32                echo '<div class="chart-1-image image-' . esc_attr( $image_position ) . '">' . wp_kses_post( $image_html ) . '</div>';
     33        }
     34}
    2635
    27         echo '<div class="chart-1-image image-' . esc_attr( $position ) . '">
    28 <img src="' . esc_url($pimg[0]) . '" alt="' . esc_attr( $post->post_title ) . '"
    29 title="' . esc_attr( $title ) . '" />
    30 </div>';
     36// Chart description.
     37if ( $chart_post->post_content ) {
     38        echo apply_filters( 'the_content', $chart_post->post_content ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output of the core the_content filter.
     39}
    3140
    32 endif;
    33 if ( $post_data->post_content ) :
    34          $content = apply_filters( 'the_content', $post_data->post_content );
    35         echo $content;
    36 endif;
     41// Chart table.
     42if ( $assets['chart-table'] ) {
     43        $this->productsize_chart_display_table( $assets['chart-table'] );
     44}
    3745
    38 if ( $assets['chart-table'] ) :
    39          $this->productsize_chart_display_table( $assets['chart-table'] );
    40 endif;
     46// Additional charts.
     47if ( $enable_additional_chart ) {
     48        $extra_tag = $this->heading_tag( $this->default_assets['productsize-chart-additional-title'], 'h3' );
    4149
    42          // chart 1 content goes here
    43 if ( $enable_additional_chart == 1 ) :
    44 
    45         $title_additional = $this->default_assets['productsize-chart-additional-title'];
    46         $title2            = ! empty( $title_additional ) ? $title_additional : 'h3';
    47 
    48         if ( $assets['chart-1'] ) :
    49                 $title_c1    = $assets['chart-1'][0]['chart-title'];
    50                 $image_c1    = $assets['chart-1'][0]['chart-image'];
    51                 $content_c1  = $assets['chart-1'][0]['chart-content'];
    52                 $position_c1 = $assets['chart-1'][0]['image-position'] == 'left' ? 'image-left' : 'image-right';
    53                 $chart_c1    = $assets['chart-1'][0]['chart-table'];
    54 
    55                 echo '<div class="add-chart-1">';
    56                 printf( '<%1$s id="modal1Title">%2$s</%3$s>', esc_attr($title2), wp_kses_post($title_c1), esc_attr($title2) );
    57 
    58                 if ( $image_c1 ) :
    59                         $img = wp_get_attachment_image_src( $image_c1, 'full' );
    60                         echo '<div class="chart-1-image ' . esc_attr($position_c1) . '"><img src="' . esc_url($img[0]) . '" alt="' . esc_attr($title_c1) . '"
    61 title="' . esc_attr($title_c1) . '" />
    62 </div>';
    63                 endif;
    64 
    65                 if ( $content_c1 ) {
    66                         echo apply_filters( 'the_content', $content_c1 );
     50        foreach ( array( 1, 2 ) as $n ) {
     51                $extra = $assets[ 'chart-' . $n ];
     52                if ( empty( $extra ) || ( '' === $extra['title'] && ! $extra['image'] && '' === $extra['content'] && '' === $extra['table'] ) ) {
     53                        continue;
    6754                }
    6855
    69                 if ( $chart_c1 ) {
    70                         $this->productsize_chart_display_table( $chart_c1 );
     56                echo '<div class="add-chart-' . absint( $n ) . '">';
     57                printf( '<%1$s id="modal1Title">%2$s</%1$s>', esc_attr( $extra_tag ), wp_kses_post( $extra['title'] ) );
     58
     59                if ( $extra['image'] ) {
     60                        $image_html = wp_get_attachment_image( $extra['image'], 'full', false, array( 'alt' => $extra['title'] ) );
     61                        if ( $image_html ) {
     62                                echo '<div class="chart-' . absint( $n ) . '-image image-' . esc_attr( $extra['position'] ) . '">' . wp_kses_post( $image_html ) . '</div>';
     63                        }
     64                }
     65
     66                if ( $extra['content'] ) {
     67                        echo apply_filters( 'the_content', $extra['content'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output of the core the_content filter.
     68                }
     69
     70                if ( $extra['table'] ) {
     71                        $this->productsize_chart_display_table( $extra['table'] );
    7172                }
    7273
    7374                echo '</div><div class="clear"></div>';
     75        }
     76}
    7477
    75 endif;
    76 
    77         if ( $assets['chart-2'] ) :
    78 
    79                 $title_c2    = $assets['chart-2'][0]['chart-title-1'];
    80                 $image_c2    = $assets['chart-2'][0]['chart-image-1'];
    81                 $content_c2  = $assets['chart-2'][0]['chart-content-1'];
    82                 $position_c2 = $assets['chart-2'][0]['image-position-1'] == 'left' ? 'image-left' : 'image-right';
    83                 $chart_c2    = $assets['chart-2'][0]['chart-table-1'];
    84 
    85                 echo '<div class="add-chart-2">';
    86                 printf( '<%1$s id="modal1Title">%2$s</%3$s>', esc_attr($title2), wp_kses_post($title_c2), esc_attr($title2) );
    87                 if ( $image_c2 ) :
    88                          $img = wp_get_attachment_image_src( $image_c2, 'full' );
    89                          echo '<div class="chart-2-image ' . esc_attr($position_c2) . '">
    90 <img src="' . esc_url($img[0]) . '" alt="' . esc_attr($title_c2) . ' ?>"
    91 title="' . esc_attr($title_c2) . '" />
    92 </div>';
    93         endif;
    94 
    95                 if ( $content_c2 ) {
    96                         echo apply_filters( 'the_content', $content_c2 );
    97                 }
    98 
    99                 if ( $chart_c2 ) {
    100                         $this->productsize_chart_display_table( $chart_c2 );
    101                 }
    102 
    103                 echo '</div>';
    104 
    105 endif;
    106 endif;
    107 
    108 
     78// Optional credit link. Opt-in: only shown when the site owner enabled it in the plugin settings.
     79if ( 1 === (int) $this->default_assets['productsize-chart-show-credit'] ) {
     80        $credit = sprintf(
     81                /* translators: %s: link to Sizegram. */
     82                esc_html__( 'Size chart by %s', 'productsize-chart-for-woocommerce' ),
     83                '<a href="' . esc_url( 'https://sizegram.com/' ) . '" target="_blank" rel="noopener">Sizegram</a>'
     84        );
     85        echo '<p class="productsize-chart-credit">' . wp_kses_post( apply_filters( 'productsize_chart_credit_html', $credit ) ) . '</p>';
     86}
  • productsize-chart-for-woocommerce/tags/1.2.0/readme.txt

    r3070321 r3789847  
    1 === Product Size Chart for Woocommerce ===
     1=== Product Size Chart & Size Guide for WooCommerce ===
    22Contributors: giucu91, knaldi2020
    33
    4 Tags: size Chart for woocommerce, product chart for woocommerce, product chart, Sizegram, woocommerce, size chart, product size chart for woo, woocommerce size chart, product size chart, product size chart for woocommerce, product size chart for woo
    5 Requires at least: 4.0
    6 Tested up to: 6.4
    7 Stable tag: 1.1.4
     4Tags: size chart, size guide, woocommerce, size table, product size chart
     5Requires at least: 6.5
     6Tested up to: 7.1
     7Requires PHP: 7.4
     8Requires Plugins: woocommerce
     9Stable tag: 1.2.0
    810License: GPLv2 or later
    911License URI: http://www.gnu.org/licenses/gpl-2.0.html
    1012
    11 This plugin allow you to use size charts to products on woocommerce.
     13Add size charts and size guides to WooCommerce products. Show them as a pop up or tab, per product or category, and reduce returns.
    1214
    1315== Description ==
    14 Reduce Returns with Sizegram Size Charts For WooCommerce. If you are hosting Woocommerce store and wanna give your customers some more information about your product then Product Size Chart for Woocommerce is a great piece of plugin to give you peace of mind. This plugin allow you to create unlimited charts and display directly to products or categories.
     16Reduce returns with Sizegram size charts for WooCommerce. Give your customers the size information they need right on the product page: a clear size guide with a size table, in a pop up or in a product tab.
    1517
    16 Product Size Chart for Woocommerce allow you to show the corresponding values of the product dimensions, height, weight, meters etc. The size guide table allows you to add multiple rows or column and insert your size guide info without requiring any html knowledge.
     18Product Size Chart & Size Guide for WooCommerce lets you create unlimited size charts and show them on the products or product categories you choose. Add rows and columns to the size table without any HTML knowledge. Use it for clothing, shoes, jewelry, furniture or anything else that comes in sizes: chest, waist, height, weight, length in cm or inches.
    1719
    18 Enable additional chart so you can display more then one table to your product page.
     20= What you can do =
     21* Create unlimited size charts and size guides.
     22* Assign a chart to one or more products, or to one or more product categories.
     23* Show the chart as a modal pop up (with a button) or as an extra product tab.
     24* Add and edit table rows and columns in a simple table editor.
     25* Add an image and text to a chart, and show up to two additional charts in the same pop up or tab.
     26* Choose table styles, colors, button style, button label and overlay.
     27* Set default settings once and override colors and style per chart.
    1928
    20 Select the look of your chart by choosing table styles, colors, buttons style, text etc.
     29= How it works =
     301. Create a chart under Size Chart > Add Chart.
     312. Fill in the size table and choose pop up or tab.
     323. Select the product categories, or pick the chart on a single product.
     334. Visitors see a "Size Guide" button or tab on the product page.
    2134
    22 With this plugin you can assign single chart to multiple products or directly assign charts to product categories.
     35The plugin does not contact external servers and does not collect data.
    2336
    24 Decide whether you wanna show the chart as modal pop up or in a tab.
    25 
    26 Original plugin was developed by: Nabaraj Chapagain( https://profiles.wordpress.org/nabaraj-chapagain/ ). On 06-09-2020 I’ve taken over and I will keep maintaning this plugin. Since 30-01-2024 the plugin has been transferred to Knaldi2020, and will be also know as sizegram as from 2024 . We will keep maintaining and improving this plugin.
     37Original plugin was developed by: Nabaraj Chapagain ( https://profiles.wordpress.org/nabaraj-chapagain/ ). On 06-09-2020 giucu91 took over and maintained this plugin. Since 30-01-2024 the plugin has been transferred to Knaldi2020, and is also known as Sizegram from 2024. We will keep maintaining and improving this plugin.
    2738
    2839Plugin information - <a href ="https://sizegram.com" target="_blank">Click here for sizegram.com</a>
    2940
    30 = Features =   
    31 1. Create unlimited Charts.
    32 2. Assign chart to single or multiple products.
    33 3. Assign chart to single or multiple categories.
     41= Features =
     421. Create unlimited charts.
     432. Assign a chart to single or multiple products.
     443. Assign a chart to single or multiple categories.
    34454. Easy to use custom fields for color, buttons, overlay etc.
    35 5. Add/Edit multiple row on chart table as per your requirements.
    36 6. Multiple Table Styles.
    37 7. Default setting available.
     465. Add/edit multiple rows and columns in the chart table.
     476. Multiple table styles.
     487. Default settings available.
    38498. Customizable text, color, button, overlay.
    39 9. Additional Size charts can be added to products.
     509. Additional size charts can be added to products.
     51
     52== Installation ==
     531. Upload the plugin to the '/wp-content/plugins/' directory, or install it from the Plugins screen.
     542. Activate the plugin through the 'Plugins' menu in WordPress. WooCommerce must be active.
     553. Add a chart from the "Size Chart" menu in the left hand side menu bar.
     564. Manage the default settings under Size Chart > Settings.
     57
     58== Frequently Asked Questions ==
     59
     60= How do I add a size chart to a product? =
     61Create a chart under Size Chart > Add Chart. Then either select the product categories on the chart, or open the product and pick the chart in the "Select Chart" box. A chart picked on a product always wins over a chart assigned to its category.
     62
     63= Can I use one size chart for a whole category? =
     64Yes. Select one or more product categories on the chart and it will show on every product in those categories.
     65
     66= Can I show the size guide as a pop up or as a tab? =
     67Yes. Choose "Modal Pop Up" or "Additional Tab" on each chart. For a pop up you can also choose where the button appears on the product page.
     68
     69= Can I show more than one size table on a product? =
     70Yes. Enable "Additional Chart" in Size Chart > Settings and add up to two extra charts to the same chart.
     71
     72= Does the plugin work with WooCommerce HPOS (High-Performance Order Storage)? =
     73Yes. The plugin does not read or write orders, and it declares compatibility with HPOS and the cart and checkout blocks.
     74
     75= Does the plugin contact external servers? =
     76No. All charts are stored in your own WordPress database.
     77
     78= Does the plugin show a link to Sizegram on my site? =
     79Only if you turn it on. Under Size Chart > Settings you can enable "Link to Sizegram", which adds a small "Size chart by Sizegram" link below the size chart. The plugin is free and we do not ask for a subscription; this link is our friendly alternative if you want to support us. It is off by default and never shown without your permission. Developers can change or remove the text with the `productsize_chart_credit_html` filter.
     80
     81= The size chart button does not show up. What should I check? =
     82Check that the chart is published, that it is assigned to the product (or one of its categories), and that your theme uses the standard WooCommerce single product template. Developers can change the button position with the `productsize_chart_button_hook` and `productsize_chart_button_priority` filters.
    4083
    4184== Screenshots ==
    … …  
    48917. Tab example single product page.
    4992
    50 == Installation Guide ==
    51 1. Upload the plugin to the '/wp-content/plugins/' directory
    52 2. Activate the plugin through the 'Plugins' menu in WordPress
    53 3. Add chart from "Charts" menu at the left hand side menu bar
    54 4. Manage default setting through Size Chart >  settings
     93== Changelog ==
    5594
    56 == Changelog ==
     95= 1.2.0 =
     96* Tested up to WordPress 7.1 and WooCommerce 11.1. Requires WordPress 6.5, PHP 7.4 and WooCommerce.
     97* New: optional "Size chart by Sizegram" link below the size chart. Off by default; turn it on under Size Chart > Settings.
     98* Declared compatibility with WooCommerce HPOS and the cart and checkout blocks.
     99* Security: nonce, capability and input checks on every save action, escaped output, validated settings.
     100* Fixed: content, image position and table of "Chart 2" were not shown again after saving.
     101* Fixed: image position of the additional charts was not saved.
     102* Fixed: padding was rendered as "10pxpx" when entered as "10px".
     103* Fixed: the extra button CSS class setting had no effect.
     104* Fixed: PHP 8 warnings, and a fatal error when a chart table contained invalid data.
     105* Fixed: uninstall now removes the plugin settings.
     106* Improved: the chart is looked up once per product page, nothing runs on other pages, styles are added with wp_add_inline_style.
     107* Removed unused files.
    57108
    58109= 1.1.4 =
  • productsize-chart-for-woocommerce/tags/1.2.0/uninstall.php

    r1337008 r3789847  
    44 * Fired when the plugin is uninstalled.
    55 *
     6 * Removes the plugin settings only. Charts (post type "chart") and their
     7 * meta are user content and are intentionally left in place.
     8 *
    69 * @since      1.0.0
    710 *
    8  * @package    nc-size-chart-for-woocommerce
     11 * @package    productsize-chart-for-woocommerce
    912 */
    1013
    … …  
    1417}
    1518
    16 delete_option('nc_size_chart_settings');
    17 
    18 
     19delete_option( 'productsize_chart_settings' );
     20// Legacy option name used by early versions.
     21delete_option( 'nc_size_chart_settings' );
Note: See TracChangeset for help on using the changeset viewer.