'publish', 'visibility' => 'catalog', 'stock_status' => 'instock', 'type' => array( 'simple', 'variable', 'external' ), 'limit' => GIFTLIGHT_MAX_PRODUCTS, 'orderby' => 'menu_order', 'order' => 'ASC', ) ); $rank = 0; foreach ( $items as $p ) { $image_id = $p->get_image_id(); if ( ! $image_id ) { continue; } $image = wp_get_attachment_image_url( $image_id, 'woocommerce_single' ); if ( ! $image ) { $image = wp_get_attachment_image_url( $image_id, 'large' ); } if ( ! $image ) { continue; } $price = (float) wc_get_price_to_display( $p ); $vars = array(); if ( $p->is_type( 'variable' ) ) { $prices = $p->get_variation_prices( true ); foreach ( $prices['price'] as $vid => $vprice ) { if ( (float) $vprice > 0 ) { $vars[] = array( (string) $vid, (float) $vprice ); } } if ( $vars ) { $price = min( array_map( function ( $v ) { return $v[1]; }, $vars ) ); } } if ( $price <= 0 ) { continue; } $cols = array_map( 'strval', $p->get_category_ids() ); foreach ( $cols as $c ) { $used[ $c ] = true; } $tags = wc_get_product_terms( $p->get_id(), 'product_tag', array( 'fields' => 'names' ) ); $item = array( 'id' => (string) $p->get_id(), 'title' => giftlight_text( $p->get_name() ), 'url' => get_permalink( $p->get_id() ), 'image' => $image, 'price' => $price, 'variant' => (string) $p->get_id(), 'available' => true, 'type' => '', 'tags' => array_values( array_map( 'giftlight_text', is_array( $tags ) ? $tags : array() ) ), 'cols' => $cols, 'rank' => $rank++, ); if ( count( $vars ) > 1 ) { $item['vars'] = $vars; } $products[] = $item; } } $collections = array(); if ( $used ) { $terms = get_terms( array( 'taxonomy' => 'product_cat', 'include' => array_map( 'intval', array_keys( $used ) ), 'hide_empty' => false, ) ); if ( ! is_wp_error( $terms ) ) { foreach ( $terms as $t ) { $collections[] = array( 'id' => (string) $t->term_id, 'title' => giftlight_text( $t->name ), ); } } } $catalog = array( 'products' => $products, 'collections' => $collections, ); set_transient( 'giftlight_catalog', $catalog, 12 * HOUR_IN_SECONDS ); return $catalog; } /** * Forget the cached catalog, so the guide follows the shop's products. */ function giftlight_flush() { delete_transient( 'giftlight_catalog' ); } foreach ( array( 'woocommerce_new_product', 'woocommerce_update_product', 'woocommerce_delete_product', 'woocommerce_trash_product', 'woocommerce_product_set_stock_status', 'woocommerce_variation_set_stock_status', 'woocommerce_update_product_variation', 'created_product_cat', 'edited_product_cat', 'delete_product_cat' ) as $giftlight_hook ) { add_action( $giftlight_hook, 'giftlight_flush' ); } add_action( 'save_post_product', 'giftlight_flush' ); /** * Register the storefront script and styles (loaded only on pages that show the guide). */ function giftlight_register_assets() { wp_register_script( 'giftlight', plugins_url( 'assets/giftlight.js', GIFTLIGHT_FILE ), array(), GIFTLIGHT_VERSION, array( 'in_footer' => true, 'strategy' => 'defer', ) ); wp_register_style( 'giftlight', plugins_url( 'assets/giftlight.css', GIFTLIGHT_FILE ), array(), GIFTLIGHT_VERSION ); } add_action( 'init', 'giftlight_register_assets' ); /** * The gift guide (or quiz) as HTML: a holder with the catalog as JSON; assets/giftlight.js builds and shows it. * * @param array $atts layout (guide|quiz), title, intro. * @return string */ function giftlight_render( $atts = array() ) { if ( ! function_exists( 'wc_get_products' ) ) { return ''; } $a = shortcode_atts( array( 'layout' => get_option( 'giftlight_layout', 'guide' ), 'title' => '', 'intro' => '', ), $atts, 'giftlight' ); $catalog = giftlight_catalog(); wp_enqueue_script( 'giftlight' ); wp_enqueue_style( 'giftlight' ); $data = array( 'products' => $catalog['products'], 'collections' => $catalog['collections'], 'currency' => get_woocommerce_currency(), 'owner' => current_user_can( 'edit_pages' ), ); $json = wp_json_encode( $data, JSON_HEX_TAG | JSON_HEX_AMP | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); return sprintf( '
', esc_attr( 'quiz' === $a['layout'] ? 'quiz' : 'guide' ), '' !== $a['title'] ? ' data-title="' . esc_attr( $a['title'] ) . '"' : '', '' !== $a['intro'] ? ' data-intro="' . esc_attr( $a['intro'] ) . '"' : '', $json // Escaped by wp_json_encode with JSON_HEX_TAG, so it can't close the script element. ); } add_shortcode( 'giftlight', 'giftlight_render' ); /** * The block: "Gift guide" in the block inserter. */ function giftlight_register_block() { register_block_type( __DIR__ . '/blocks/gift-guide' ); } add_action( 'init', 'giftlight_register_block' ); if ( is_admin() ) { require_once __DIR__ . '/admin.php'; }