post_type === self::TYPE && self::active(); } /** Products are among the scanned post types (Cluster Admin adds them when a product category is chosen). */ public static function in_scope(): bool { return self::active() && in_array( self::TYPE, Scope::post_types(), true ); } /** True when WooCommerce keeps this product out of the shop's catalogue. */ public static function hidden( int $post_id ): bool { return self::active() && has_term( 'exclude-from-catalog', 'product_visibility', $post_id ); } /** * SQL (starting with " AND ") that leaves hidden products out, for a posts * table alias ('' = the posts table by its own name). '' when not a shop. */ public static function hidden_sql( string $alias = '' ): string { if ( ! self::in_scope() ) return ''; global $wpdb; $a = $alias !== '' ? $alias : $wpdb->posts; return " AND NOT ( {$a}.post_type = 'product' AND EXISTS ( SELECT 1 FROM {$wpdb->term_relationships} shtr INNER JOIN {$wpdb->term_taxonomy} shtt ON shtt.term_taxonomy_id = shtr.term_taxonomy_id AND shtt.taxonomy = 'product_visibility' INNER JOIN {$wpdb->terms} sht ON sht.term_id = shtt.term_id AND sht.slug = 'exclude-from-catalog' WHERE shtr.object_id = {$a}.ID ) )"; } /** Short description (post_excerpt) of a product, as plain text. */ public static function short_description( \WP_Post $post ): string { return trim( wp_strip_all_tags( (string) $post->post_excerpt ) ); } /** Images in a product's gallery (_product_image_gallery), not counting the main image. */ public static function gallery_count( int $post_id ): int { $g = (string) get_post_meta( $post_id, '_product_image_gallery', true ); return $g === '' ? 0 : count( array_filter( explode( ',', $g ) ) ); } }