Changeset 3366418
- Timestamp:
- 09/23/2025 11:25:28 AM (5 months ago)
- Location:
- wiser-review/trunk
- Files:
-
- 2 edited
-
readme.txt (modified) (1 diff)
-
wiser-review.php (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
wiser-review/trunk/readme.txt
r3359694 r3366418 130 130 = 2.3 = 131 131 Optimize performance, logo, css fixed & Star rating rendering at server side. 132 133 = 2.4 = 134 Google Rich review schema-if zero review, Don't generate the schema, Other improvement -
wiser-review/trunk/wiser-review.php
r3359694 r3366418 4 4 * Plugin URI: https://wiserreview.com 5 5 * 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. 36 * Version: 2.4 7 7 * Author: Wiser Notify 8 8 * Requires Plugins: woocommerce … … 22 22 define( 'WISERRW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 23 23 define( 'WISERRW_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); 24 define( 'WISERRW_PLUGIN_VERSION', 2. 3);24 define( 'WISERRW_PLUGIN_VERSION', 2.4 ); 25 25 define( 'WISERRW_API_HOST', 'https://api.wiserreview.com/api/woocommerce/' ); 26 26 … … 1061 1061 add_action( 'woocommerce_after_product_object_save', 'wiserrw_product_update_hook', 99, 1 ); 1062 1062 1063 1063 1064 function 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 -------------------- // 1201 1208 1202 1209 function wiserrw_custom_endpoints() { … … 1277 1284 return; 1278 1285 } 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'] : ''; 1281 1288 $wsid = get_option( 'wiserrw_wsid', '' ); 1282 1289 // Verify API key if 'verify_api' is true and 'wiserrw_wsid' matches … … 1332 1339 continue; 1333 1340 } 1334 $arrPid[] = (string)$p_id_arr[$i]; 1341 // ✅ Reset on every loop 1342 $arrPid = array( (string) $p_id_arr[$i] ); 1335 1343 $schema_array = array(); 1336 1344 $body = array( … … 1360 1368 if( $wdtyp == 'main' ){ 1361 1369 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 } 1374 1382 if( $wdtyp == 'star_rating' ) { 1375 1383 $star_rating_html = $row['dataRating'][0]['html']; … … 1402 1410 $json_schema = json_encode($schema_array,JSON_UNESCAPED_SLASHES); 1403 1411 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 } 1405 1417 } 1406 1418 } … … 1408 1420 } 1409 1421 } 1422 1410 1423 1411 1424 // Add schema only on WooCommerce single product pages
Note: See TracChangeset
for help on using the changeset viewer.