Plugin Directory

Changeset 3366418


Ignore:
Timestamp:
09/23/2025 11:25:28 AM (5 months ago)
Author:
wisernotify
Message:

Updating trunk to version 2.4

Location:
wiser-review/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • wiser-review/trunk/readme.txt

    r3359694 r3366418  
    130130= 2.3 =
    131131Optimize performance, logo, css fixed & Star rating rendering at server side.
     132
     133= 2.4 =
     134Google Rich review schema-if zero review, Don't generate the schema, Other improvement
  • wiser-review/trunk/wiser-review.php

    r3359694 r3366418  
    44 * Plugin URI: https://wiserreview.com
    55 * Description: Wiser Review module helps you collect and display product reviews, star ratings, and nudges. It also automates review requests via email to boost custom engagement and conversions.
    6  * Version: 2.3
     6 * Version: 2.4
    77 * Author: Wiser Notify
    88 * Requires Plugins: woocommerce
     
    2222define( 'WISERRW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
    2323define( 'WISERRW_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
    24 define( 'WISERRW_PLUGIN_VERSION', 2.3 );
     24define( 'WISERRW_PLUGIN_VERSION', 2.4 );
    2525define( 'WISERRW_API_HOST', 'https://api.wiserreview.com/api/woocommerce/' );
    2626
     
    10611061add_action( 'woocommerce_after_product_object_save', 'wiserrw_product_update_hook', 99, 1 );
    10621062
     1063
    10631064function wiserrw_product_update_hook( $product ) {
    1064     if ( ! $product instanceof WC_Product ) {
    1065         return;
    1066     }
    1067 
    1068     $p_id = $product->get_id();
    1069 
    1070     // Skip autosaves / revisions
    1071     if ( wp_is_post_autosave( $p_id ) || wp_is_post_revision( $p_id ) ) {
    1072         return;
    1073     }
    1074 
    1075     $is_variation = $product instanceof WC_Product_Variation;
    1076     $parent_id    = $is_variation ? $product->get_parent_id() : $p_id;
    1077 
    1078     // --- Current values we watch ---
    1079     $name      = (string) $product->get_name();
    1080     $permalink = (string) get_permalink( $is_variation ? $parent_id : $p_id );
    1081 
    1082     // Effective image id (variation image, else parent/simple image)
    1083     $effective_image_id = (int) $product->get_image_id();
    1084     if ( ! $effective_image_id ) {
    1085         $effective_image_id = (int) get_post_thumbnail_id( $is_variation ? $parent_id : $p_id );
    1086     }
    1087     $image_id = (string) $effective_image_id;
    1088 
    1089     // SKU fingerprint (simple/variation = own SKU, variable parent = all child SKUs)
    1090     if ( $product->is_type( 'variable' ) && ! $is_variation ) {
    1091         $child_skus = array();
    1092         foreach ( $product->get_children() as $vid ) {
    1093             $vsku = (string) get_post_meta( $vid, '_sku', true );
    1094             if ( $vsku !== '' ) {
    1095                 $child_skus[] = $vsku;
    1096             }
    1097         }
    1098         sort( $child_skus, SORT_NATURAL | SORT_FLAG_CASE );
    1099         $sku_fingerprint = implode( ',', $child_skus );
    1100     } else {
    1101         $sku_fingerprint = (string) $product->get_sku();
    1102     }
    1103 
    1104     // Barcode / GTIN (variation gets its own; others use product/attributes)
    1105     if ( $is_variation ) {
    1106         $barcode = get_post_meta( $p_id, 'hwp_var_gtin', true )
    1107             ?: get_post_meta( $parent_id, 'hwp_product_gtin', true )
    1108             ?: $product->get_attribute( 'GTIN' )
    1109             ?: $product->get_attribute( 'EAN' )
    1110             ?: $product->get_attribute( 'ISBN' )
    1111             ?: get_post_meta( $p_id, '_global_unique_id', true );
    1112     } else {
    1113         $barcode = get_post_meta( $p_id, 'hwp_product_gtin', true )
    1114             ?: $product->get_attribute( 'GTIN' )
    1115             ?: $product->get_attribute( 'EAN' )
    1116             ?: $product->get_attribute( 'ISBN' )
    1117             ?: get_post_meta( $p_id, '_global_unique_id', true );
    1118     }
    1119     $barcode = (string) $barcode;
    1120 
    1121     // Fingerprint of watched fields (name, URL, image, SKU(s), barcode)
    1122     $new_hash = md5( $name . '|' . $permalink . '|' . $image_id . '|' . $sku_fingerprint . '|' . $barcode );
    1123     $old_hash = (string) get_post_meta( $p_id, '_wiserrw_watch_hash', true );
    1124 
    1125     // If nothing important changed, exit
    1126     if ( $new_hash === $old_hash ) {
    1127         return;
    1128     }
    1129 
    1130     // --- Prepare payload (aligned with your original) ---
    1131     $wiserrw_api_settings = get_option( 'wiserrw_api_settings' );
    1132     if ( empty( $wiserrw_api_settings['wiserrw_api_key'] ) ) {
    1133         return;
    1134     }
    1135     $api_host      = constant( 'WISERRW_API_HOST' );
    1136     $api_key       = $wiserrw_api_settings['wiserrw_api_key'];
    1137     $wsid          = get_option( 'wiserrw_wsid', true );
    1138     $automation_id = get_option( 'wiserrw_automation_id', true );
    1139     if ( ! $wsid || ! $automation_id ) {
    1140         return;
    1141     }
    1142 
    1143     // arrsku (mirror your original behavior)
    1144     $arrsku = array();
    1145     if ( $product->is_type( 'variable' ) && ! $is_variation ) {
    1146         foreach ( $product->get_children() as $vid ) {
    1147             $vsku = (string) get_post_meta( $vid, '_sku', true );
    1148             if ( $vsku !== '' ) {
    1149                 $arrsku[] = $vsku;
    1150             }
    1151         }
    1152     } else {
    1153         if ( $sku_fingerprint !== '' ) {
    1154             $arrsku[] = $sku_fingerprint;
    1155         }
    1156     }
    1157 
    1158     // Image URL from effective image id, with placeholder fallback
    1159     $thumb_id  = $effective_image_id;
    1160     $img_src   = $thumb_id ? wp_get_attachment_image_src( $thumb_id, 'shop_single' ) : false;
    1161     $img_url   = ( is_array( $img_src ) && isset( $img_src[0] ) ) ? $img_src[0] : wc_placeholder_img_src( 'shop_single' );
    1162 
    1163     $product_json = array(
    1164         'pid'     => (string) $p_id,
    1165         'arrsku'  => $arrsku,
    1166         'shp'     => get_site_url(),
    1167         'wsid'    => $wsid,
    1168         'pn'      => $name ?: get_the_title( $parent_id ),
    1169         'piu'     => $img_url,
    1170         'pu'      => $permalink, // product URL
    1171         'barcode' => $barcode,
    1172     );
    1173 
    1174     $args = array(
    1175         'method'   => 'POST',
    1176         'blocking' => true,
    1177         'headers'  => array( 'Content-Type' => 'application/json' ),
    1178         'body'     => wp_json_encode( array( 'products' => array( $product_json ) ) ),
    1179     );
    1180 
    1181     // Clear flag before send (like your original flow)
    1182     delete_post_meta( $p_id, '_wiserrw_product_registered' );
    1183 
    1184     $response = wp_safe_remote_post( $api_host . 'productWebhook?wsid=' . $wsid . '&key=' . $api_key, $args );
    1185     if ( is_wp_error( $response ) ) {
    1186         return;
    1187     }
    1188 
    1189     if ( (int) wp_remote_retrieve_response_code( $response ) === 200 ) {
    1190         update_post_meta( $p_id, '_wiserrw_product_registered', '1' );
    1191         update_post_meta( $p_id, '_wiserrw_watch_hash', $new_hash );
    1192     }
    1193 }
    1194 
    1195 
    1196 
    1197 
    1198 
    1199 
    1200 
     1065    if ( ! $product instanceof WC_Product ) {
     1066        return;
     1067    }
     1068
     1069    $p_id = $product->get_id();
     1070
     1071    // Skip autosaves / revisions
     1072    if ( wp_is_post_autosave( $p_id ) || wp_is_post_revision( $p_id ) ) {
     1073        return;
     1074    }
     1075
     1076    // Skip background cron or ajax jobs (vendor imports often run this way)
     1077    if ( ( defined( 'DOING_CRON' ) && DOING_CRON ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
     1078        return;
     1079    }
     1080
     1081    $is_variation = $product instanceof WC_Product_Variation;
     1082    $parent_id    = $is_variation ? $product->get_parent_id() : $p_id;
     1083
     1084    // --- Watched fields ---
     1085
     1086    // Name
     1087    $name = (string) $product->get_name();
     1088
     1089    // Permalink (normalize: strip trailing slash)
     1090    $permalink = untrailingslashit( (string) get_permalink( $is_variation ? $parent_id : $p_id ) );
     1091
     1092    // Image ID (normalize to string "0" if none)
     1093    $effective_image_id = (int) $product->get_image_id();
     1094    if ( ! $effective_image_id ) {
     1095        $effective_image_id = (int) get_post_thumbnail_id( $is_variation ? $parent_id : $p_id );
     1096    }
     1097    $image_id = (string) ( $effective_image_id ?: 0 );
     1098
     1099    // SKU fingerprint
     1100    if ( $product->is_type( 'variable' ) && ! $is_variation ) {
     1101        $child_skus = array();
     1102        foreach ( $product->get_children() as $vid ) {
     1103            $vsku = strtolower( trim( (string) get_post_meta( $vid, '_sku', true ) ) );
     1104            if ( $vsku !== '' ) {
     1105                $child_skus[] = $vsku;
     1106            }
     1107        }
     1108        sort( $child_skus, SORT_NATURAL | SORT_FLAG_CASE );
     1109        $sku_fingerprint = implode( ',', $child_skus );
     1110    } else {
     1111        $sku_fingerprint = strtolower( trim( (string) $product->get_sku() ) );
     1112    }
     1113
     1114    // Barcode / GTIN (normalize)
     1115    if ( $is_variation ) {
     1116        $barcode = get_post_meta( $p_id, 'hwp_var_gtin', true )
     1117            ?: get_post_meta( $parent_id, 'hwp_product_gtin', true )
     1118            ?: $product->get_attribute( 'GTIN' )
     1119            ?: $product->get_attribute( 'EAN' )
     1120            ?: $product->get_attribute( 'ISBN' )
     1121            ?: get_post_meta( $p_id, '_global_unique_id', true );
     1122    } else {
     1123        $barcode = get_post_meta( $p_id, 'hwp_product_gtin', true )
     1124            ?: $product->get_attribute( 'GTIN' )
     1125            ?: $product->get_attribute( 'EAN' )
     1126            ?: $product->get_attribute( 'ISBN' )
     1127            ?: get_post_meta( $p_id, '_global_unique_id', true );
     1128    }
     1129    $barcode = strtolower( trim( (string) $barcode ) );
     1130
     1131    // Build watch hash
     1132    $new_hash = md5( $name . '|' . $permalink . '|' . $image_id . '|' . $sku_fingerprint . '|' . $barcode );
     1133    $old_hash = (string) get_post_meta( $p_id, '_wiserrw_watch_hash', true );
     1134
     1135    // If nothing changed, exit
     1136    if ( $new_hash === $old_hash ) {
     1137        return;
     1138    }
     1139
     1140    // --- Prepare payload ---
     1141
     1142    $wiserrw_api_settings = get_option( 'wiserrw_api_settings' );
     1143    if ( empty( $wiserrw_api_settings['wiserrw_api_key'] ) ) {
     1144        return;
     1145    }
     1146    $api_host      = constant( 'WISERRW_API_HOST' );
     1147    $api_key       = $wiserrw_api_settings['wiserrw_api_key'];
     1148    $wsid          = get_option( 'wiserrw_wsid', true );
     1149    $automation_id = get_option( 'wiserrw_automation_id', true );
     1150    if ( ! $wsid || ! $automation_id ) {
     1151        return;
     1152    }
     1153
     1154    // Build arrsku
     1155    $arrsku = array();
     1156    if ( $product->is_type( 'variable' ) && ! $is_variation ) {
     1157        foreach ( $product->get_children() as $vid ) {
     1158            $vsku = strtolower( trim( (string) get_post_meta( $vid, '_sku', true ) ) );
     1159            if ( $vsku !== '' ) {
     1160                $arrsku[] = $vsku;
     1161            }
     1162        }
     1163    } else {
     1164        if ( $sku_fingerprint !== '' ) {
     1165            $arrsku[] = $sku_fingerprint;
     1166        }
     1167    }
     1168
     1169    // Image URL (fallback to placeholder)
     1170    $thumb_id = $effective_image_id;
     1171    $img_src  = $thumb_id ? wp_get_attachment_image_src( $thumb_id, 'shop_single' ) : false;
     1172    $img_url  = ( is_array( $img_src ) && isset( $img_src[0] ) ) ? $img_src[0] : wc_placeholder_img_src( 'shop_single' );
     1173
     1174    $product_json = array(
     1175        'pid'     => (string) $p_id,
     1176        'arrsku'  => $arrsku,
     1177        'shp'     => get_site_url(),
     1178        'wsid'    => $wsid,
     1179        'pn'      => $name ?: get_the_title( $parent_id ),
     1180        'piu'     => $img_url,
     1181        'pu'      => $permalink,
     1182        'barcode' => $barcode,
     1183    );
     1184
     1185    $args = array(
     1186        'method'   => 'POST',
     1187        'blocking' => true,
     1188        'headers'  => array( 'Content-Type' => 'application/json' ),
     1189        'body'     => wp_json_encode( array( 'products' => array( $product_json ) ) ),
     1190    );
     1191
     1192    // Clear flag before sending
     1193    delete_post_meta( $p_id, '_wiserrw_product_registered' );
     1194
     1195    $response = wp_safe_remote_post( $api_host . 'productWebhook?wsid=' . $wsid . '&key=' . $api_key, $args );
     1196    if ( is_wp_error( $response ) ) {
     1197        return;
     1198    }
     1199
     1200    if ( (int) wp_remote_retrieve_response_code( $response ) === 200 ) {
     1201        update_post_meta( $p_id, '_wiserrw_product_registered', '1' );
     1202        update_post_meta( $p_id, '_wiserrw_watch_hash', $new_hash );
     1203    }
     1204}
     1205
     1206
     1207// -------------------- Custom REST API Endpoints -------------------- //
    12011208
    12021209function wiserrw_custom_endpoints() {
     
    12771284        return;
    12781285    }
    1279     $verify = $query_params['verify_api'];
    1280     $wsid_param = $query_params['wiserrw_wsid'];
     1286$verify     = isset($query_params['verify_api']) ? $query_params['verify_api'] : '';
     1287$wsid_param = isset($query_params['wiserrw_wsid']) ? $query_params['wiserrw_wsid'] : '';
    12811288    $wsid = get_option( 'wiserrw_wsid', '' );
    12821289     // Verify API key if 'verify_api' is true and 'wiserrw_wsid' matches
     
    13321339            continue;
    13331340        }
    1334         $arrPid[] = (string)$p_id_arr[$i];
     1341        // ✅ Reset on every loop
     1342    $arrPid = array( (string) $p_id_arr[$i] );
    13351343        $schema_array = array();
    13361344        $body = array(
     
    13601368                if( $wdtyp == 'main' ){
    13611369
    1362                 $schema_array['@context'] = "https://schema.org";
    1363                 $schema_array['@type'] = "Product";
    1364                 $schema_array['url'] = get_the_permalink($p_id_arr[$i]);
    1365                 $schema_array['name'] = get_the_title($p_id_arr[$i]);
    1366                 $schema_array['aggregateRating'] = array(
    1367                     '@type' => 'AggregateRating',
    1368                     'ratingValue' => $row['dataCount']['avgrtng'],
    1369                     'reviewCount' => $row['dataCount']['prtng'],
    1370                     'bestRating' => '5',
    1371                     'worstRating' => '1',
    1372                 );
    1373             }
     1370                    $schema_array['@context'] = "https://schema.org";
     1371                    $schema_array['@type'] = "Product";
     1372                    $schema_array['url'] = get_the_permalink($p_id_arr[$i]);
     1373                    $schema_array['name'] = get_the_title($p_id_arr[$i]);
     1374                    $schema_array['aggregateRating'] = array(
     1375                        '@type' => 'AggregateRating',
     1376                        'ratingValue' => $row['dataCount']['avgrtng'],
     1377                        'reviewCount' => $row['dataCount']['prtng'],
     1378                        'bestRating' => '5',
     1379                        'worstRating' => '1',
     1380                    );
     1381                }
    13741382                if( $wdtyp == 'star_rating' ) {
    13751383                    $star_rating_html = $row['dataRating'][0]['html'];
     
    14021410                $json_schema = json_encode($schema_array,JSON_UNESCAPED_SLASHES);
    14031411               
    1404                 update_post_meta( $p_id_arr[$i], 'wiserrw_schema_json', $json_schema );
     1412                if( $row['dataCount']['prtng'] > 0 ) {
     1413                    update_post_meta( $p_id_arr[$i], 'wiserrw_schema_json', $json_schema );
     1414                } else {
     1415                    delete_post_meta( $p_id_arr[$i], 'wiserrw_schema_json' );
     1416                }
    14051417            }
    14061418        }
     
    14081420    }
    14091421}
     1422
    14101423
    14111424// Add schema only on WooCommerce single product pages
Note: See TracChangeset for help on using the changeset viewer.