BONGOTO_WOOCOMMERCE_ORIENT_LANDSCAPE_MIN => Landscape * ratio < BONGOTO_WOOCOMMERCE_ORIENT_PORTRAIT_MAX => Portrait * else => Square */ if ( ! defined( 'BONGOTO_WOOCOMMERCE_ORIENT_LANDSCAPE_MIN' ) ) { define( 'BONGOTO_WOOCOMMERCE_ORIENT_LANDSCAPE_MIN', 1.10 ); } if ( ! defined( 'BONGOTO_WOOCOMMERCE_ORIENT_PORTRAIT_MAX' ) ) { define( 'BONGOTO_WOOCOMMERCE_ORIENT_PORTRAIT_MAX', 0.90 ); } /* Back-compat: old constant names, if something external still uses them. */ if ( ! defined( 'BM_ORIENT_LANDSCAPE_MIN' ) ) { define( 'BM_ORIENT_LANDSCAPE_MIN', BONGOTO_WOOCOMMERCE_ORIENT_LANDSCAPE_MIN ); } if ( ! defined( 'BM_ORIENT_PORTRAIT_MAX' ) ) { define( 'BM_ORIENT_PORTRAIT_MAX', BONGOTO_WOOCOMMERCE_ORIENT_PORTRAIT_MAX ); } /** * ------------------------------------------------------------------------- * 1) Ensure product_cat terms exist * ------------------------------------------------------------------------- */ add_action( 'init', function () { $cats = array( 'Landscape', 'Portrait', 'Square' ); foreach ( $cats as $name ) { if ( ! term_exists( $name, 'product_cat' ) ) { wp_insert_term( $name, 'product_cat', array( 'slug' => sanitize_title( $name ), /* translators: product category description for auto orientation terms. */ 'description' => __( 'Auto-assigned by image orientation', 'bongoto-woocommerce' ), ) ); } } } ); /** * ------------------------------------------------------------------------- * 2) Detect orientation from an attachment id (helper) * ------------------------------------------------------------------------- * * @param int $attachment_id Attachment ID. * @return string|null 'Landscape'|'Portrait'|'Square' or null on failure. */ function bongoto_woocommerce_detect_orientation_from_attachment( $attachment_id ) : ?string { if ( ! $attachment_id ) { return null; } $meta = wp_get_attachment_metadata( $attachment_id ); if ( is_array( $meta ) && ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) { $w = (float) $meta['width']; $h = (float) $meta['height']; } else { $file = get_attached_file( $attachment_id ); if ( ! $file || ! file_exists( $file ) ) { return null; } $size = @getimagesize( $file ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged if ( ! $size || empty( $size[0] ) || empty( $size[1] ) ) { return null; } $w = (float) $size[0]; $h = (float) $size[1]; } if ( $w <= 0 || $h <= 0 ) { return null; } $ratio = $w / $h; if ( $ratio > BONGOTO_WOOCOMMERCE_ORIENT_LANDSCAPE_MIN ) { return 'Landscape'; } if ( $ratio < BONGOTO_WOOCOMMERCE_ORIENT_PORTRAIT_MAX ) { return 'Portrait'; } return 'Square'; } /** * ------------------------------------------------------------------------- * 3) Assign orientation category to a product (core function) * ------------------------------------------------------------------------- * * @param int $product_id Product ID. */ function bongoto_woocommerce_set_product_orientation_term( $product_id ) : void { if ( get_post_type( $product_id ) !== 'product' ) { return; } $thumb_id = get_post_thumbnail_id( $product_id ); if ( ! $thumb_id ) { return; } $term_name = bongoto_woocommerce_detect_orientation_from_attachment( $thumb_id ); if ( ! $term_name ) { return; } $term_obj = get_term_by( 'name', $term_name, 'product_cat' ); if ( ! $term_obj ) { return; } // Remove existing orientation terms, keep others. $orientation_ids = array_filter( array( ( get_term_by( 'name', 'Landscape', 'product_cat' ) ) ? get_term_by( 'name', 'Landscape', 'product_cat' )->term_id : 0, ( get_term_by( 'name', 'Portrait', 'product_cat' ) ) ? get_term_by( 'name', 'Portrait', 'product_cat' )->term_id : 0, ( get_term_by( 'name', 'Square', 'product_cat' ) ) ? get_term_by( 'name', 'Square', 'product_cat' )->term_id : 0, ) ); $current_ids = wp_get_post_terms( $product_id, 'product_cat', array( 'fields' => 'ids' ) ); $new_ids = array_diff( (array) $current_ids, $orientation_ids ); $new_ids[] = (int) $term_obj->term_id; wp_set_post_terms( $product_id, $new_ids, 'product_cat', false ); // Store orientation meta for easier display/filtering later. // Keep old key for back-compat with any existing content. update_post_meta( $product_id, '_bm_orientation', $term_name ); } /** * ------------------------------------------------------------------------- * 4) Hooks — save & when thumbnail changes * ------------------------------------------------------------------------- */ add_action( 'save_post_product', function ( $post_id ) { if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) { return; } bongoto_woocommerce_set_product_orientation_term( $post_id ); }, 20 ); add_action( 'woocommerce_process_product_meta', function ( $post_id ) { bongoto_woocommerce_set_product_orientation_term( $post_id ); }, 20 ); // Re-assign orientation when thumbnail meta changes. add_action( 'updated_post_meta', function ( $meta_id, $post_id, $meta_key, $meta_value ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found if ( '_thumbnail_id' === $meta_key && 'product' === get_post_type( $post_id ) ) { bongoto_woocommerce_set_product_orientation_term( $post_id ); } }, 10, 4 ); /** * ------------------------------------------------------------------------- * 5) Badges — archive + single * ------------------------------------------------------------------------- */ add_action( 'woocommerce_before_shop_loop_item_title', function () { global $product; if ( ! $product instanceof WC_Product ) { return; } $badge = ''; if ( has_term( 'Landscape', 'product_cat', $product->get_id() ) ) { $badge = 'Landscape'; } elseif ( has_term( 'Portrait', 'product_cat', $product->get_id() ) ) { $badge = 'Portrait'; } elseif ( has_term( 'Square', 'product_cat', $product->get_id() ) ) { $badge = 'Square'; } if ( $badge ) { $badge_label = __( $badge, 'bongoto-woocommerce' ); printf( '%2$s', esc_attr( strtolower( $badge ) ), esc_html( $badge_label ) ); } }, 5 ); add_action( 'woocommerce_single_product_summary', function () { global $product; if ( ! $product instanceof WC_Product ) { return; } $badge = get_post_meta( $product->get_id(), '_bm_orientation', true ); if ( ! $badge ) { if ( has_term( 'Landscape', 'product_cat', $product->get_id() ) ) { $badge = 'Landscape'; } elseif ( has_term( 'Portrait', 'product_cat', $product->get_id() ) ) { $badge = 'Portrait'; } elseif ( has_term( 'Square', 'product_cat', $product->get_id() ) ) { $badge = 'Square'; } } if ( $badge ) { $badge_label = __( $badge, 'bongoto-woocommerce' ); printf( '