| Total Complexity | 134 |
| Total Lines | 1397 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like ProductSchema often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ProductSchema, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 15 | class ProductSchema { |
||
| 16 | |||
| 17 | /** |
||
| 18 | * Return schema for products. |
||
| 19 | * |
||
| 20 | * @return array |
||
| 21 | */ |
||
| 22 | public static function get_schema() { |
||
| 645 | } |
||
| 646 | |||
| 647 | /** |
||
| 648 | * Convert object to match data in the schema. |
||
| 649 | * |
||
| 650 | * @param \WC_Product $object Product instance. |
||
| 651 | * @param string $context Request context. Options: 'view' and 'edit'. |
||
| 652 | * @return array |
||
| 653 | */ |
||
| 654 | public static function object_to_schema( $object, $context ) { |
||
| 655 | $data = array( |
||
| 656 | 'id' => $object->get_id(), |
||
| 657 | 'name' => $object->get_name( $context ), |
||
| 658 | 'slug' => $object->get_slug( $context ), |
||
| 659 | 'permalink' => $object->get_permalink(), |
||
| 660 | 'date_created' => wc_rest_prepare_date_response( $object->get_date_created( $context ), false ), |
||
| 661 | 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created( $context ) ), |
||
| 662 | 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified( $context ), false ), |
||
| 663 | 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified( $context ) ), |
||
| 664 | 'type' => $object->get_type(), |
||
| 665 | 'status' => $object->get_status( $context ), |
||
| 666 | 'featured' => $object->is_featured(), |
||
| 667 | 'catalog_visibility' => $object->get_catalog_visibility( $context ), |
||
| 668 | 'description' => $object->get_description( $context ), |
||
| 669 | 'short_description' => $object->get_short_description( $context ), |
||
| 670 | 'sku' => $object->get_sku( $context ), |
||
| 671 | 'price' => $object->get_price( $context ), |
||
| 672 | 'regular_price' => $object->get_regular_price( $context ), |
||
| 673 | 'sale_price' => $object->get_sale_price( $context ) ? $object->get_sale_price( $context ) : '', |
||
| 674 | 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ), false ), |
||
| 675 | 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ) ), |
||
| 676 | 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ), false ), |
||
| 677 | 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ) ), |
||
| 678 | 'price_html' => $object->get_price_html(), |
||
| 679 | 'on_sale' => $object->is_on_sale( $context ), |
||
| 680 | 'purchasable' => $object->is_purchasable(), |
||
| 681 | 'total_sales' => $object->get_total_sales( $context ), |
||
| 682 | 'virtual' => $object->is_virtual(), |
||
| 683 | 'downloadable' => $object->is_downloadable(), |
||
| 684 | 'downloads' => self::get_downloads( $object ), |
||
| 685 | 'download_limit' => $object->get_download_limit( $context ), |
||
| 686 | 'download_expiry' => $object->get_download_expiry( $context ), |
||
| 687 | 'external_url' => '', |
||
| 688 | 'button_text' => '', |
||
| 689 | 'tax_status' => $object->get_tax_status( $context ), |
||
| 690 | 'tax_class' => $object->get_tax_class( $context ), |
||
| 691 | 'manage_stock' => $object->managing_stock(), |
||
| 692 | 'stock_quantity' => $object->get_stock_quantity( $context ), |
||
| 693 | 'stock_status' => $object->get_stock_status( $context ), |
||
| 694 | 'backorders' => $object->get_backorders( $context ), |
||
| 695 | 'backorders_allowed' => $object->backorders_allowed(), |
||
| 696 | 'backordered' => $object->is_on_backorder(), |
||
| 697 | 'sold_individually' => $object->is_sold_individually(), |
||
| 698 | 'weight' => $object->get_weight( $context ), |
||
| 699 | 'dimensions' => array( |
||
| 700 | 'length' => $object->get_length( $context ), |
||
| 701 | 'width' => $object->get_width( $context ), |
||
| 702 | 'height' => $object->get_height( $context ), |
||
| 703 | ), |
||
| 704 | 'shipping_required' => $object->needs_shipping(), |
||
| 705 | 'shipping_taxable' => $object->is_shipping_taxable(), |
||
| 706 | 'shipping_class' => $object->get_shipping_class(), |
||
| 707 | 'shipping_class_id' => $object->get_shipping_class_id( $context ), |
||
| 708 | 'reviews_allowed' => $object->get_reviews_allowed( $context ), |
||
| 709 | 'average_rating' => $object->get_average_rating( $context ), |
||
| 710 | 'rating_count' => $object->get_rating_count(), |
||
| 711 | 'related_ids' => wp_parse_id_list( wc_get_related_products( $object->get_id() ) ), |
||
| 712 | 'upsell_ids' => wp_parse_id_list( $object->get_upsell_ids( $context ) ), |
||
| 713 | 'cross_sell_ids' => wp_parse_id_list( $object->get_cross_sell_ids( $context ) ), |
||
| 714 | 'parent_id' => $object->get_parent_id( $context ), |
||
| 715 | 'purchase_note' => $object->get_purchase_note( $context ), |
||
| 716 | 'categories' => self::get_taxonomy_terms( $object ), |
||
| 717 | 'tags' => self::get_taxonomy_terms( $object, 'tag' ), |
||
| 718 | 'images' => self::get_images( $object ), |
||
| 719 | 'attributes' => self::get_attributes( $object ), |
||
| 720 | 'default_attributes' => self::get_default_attributes( $object ), |
||
| 721 | 'variations' => array(), |
||
| 722 | 'grouped_products' => array(), |
||
| 723 | 'menu_order' => $object->get_menu_order( $context ), |
||
| 724 | 'meta_data' => $object->get_meta_data(), |
||
| 725 | ); |
||
| 726 | |||
| 727 | // Add variations to variable products. |
||
| 728 | if ( $object->is_type( 'variable' ) ) { |
||
| 729 | $data['variations'] = $object->get_children(); |
||
| 730 | } |
||
| 731 | |||
| 732 | // Add grouped products data. |
||
| 733 | if ( $object->is_type( 'grouped' ) ) { |
||
| 734 | $data['grouped_products'] = $object->get_children(); |
||
| 735 | } |
||
| 736 | |||
| 737 | // Add external product data. |
||
| 738 | if ( $object->is_type( 'external' ) ) { |
||
| 739 | $data['external_url'] = $object->get_product_url( $context ); |
||
| 740 | $data['button_text'] = $object->get_button_text( $context ); |
||
| 741 | } |
||
| 742 | |||
| 743 | if ( 'view' === $context ) { |
||
| 744 | $data['description'] = wpautop( do_shortcode( $data['description'] ) ); |
||
| 745 | $data['short_description'] = apply_filters( 'woocommerce_short_description', $data['short_description'] ); |
||
| 746 | $data['average_rating'] = wc_format_decimal( $data['average_rating'], 2 ); |
||
| 747 | $data['purchase_note'] = wpautop( do_shortcode( $data['purchase_note'] ) ); |
||
| 748 | } |
||
| 749 | |||
| 750 | return $data; |
||
| 751 | } |
||
| 752 | |||
| 753 | /** |
||
| 754 | * Take data in the format of the schema and convert to a product object. |
||
| 755 | * |
||
| 756 | * @param \WP_REST_Request $request Request object. |
||
| 757 | * @return \WP_Error|\WC_Product |
||
| 758 | */ |
||
| 759 | public static function schema_to_object( $request ) { |
||
| 760 | $id = isset( $request['id'] ) ? (int) $request['id'] : 0; |
||
| 761 | |||
| 762 | if ( isset( $request['type'] ) ) { |
||
| 763 | $classname = '\\' . \WC_Product_Factory::get_classname_from_product_type( $request['type'] ); |
||
| 764 | |||
| 765 | if ( ! class_exists( $classname ) ) { |
||
| 766 | $classname = '\\WC_Product_Simple'; |
||
| 767 | } |
||
| 768 | |||
| 769 | $object = new $classname( $id ); |
||
| 770 | } elseif ( isset( $request['id'] ) ) { |
||
| 771 | $object = wc_get_product( $id ); |
||
| 772 | } else { |
||
| 773 | $object = new \WC_Product_Simple(); |
||
| 774 | } |
||
| 775 | |||
| 776 | if ( $object->is_type( 'variation' ) ) { |
||
| 777 | return new \WP_Error( |
||
| 778 | 'woocommerce_rest_invalid_product_id', |
||
| 779 | __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), |
||
| 780 | array( |
||
| 781 | 'status' => 404, |
||
| 782 | ) |
||
| 783 | ); |
||
| 784 | } |
||
| 785 | |||
| 786 | self::set_object_data( $object, $request ); |
||
| 787 | |||
| 788 | return $object; |
||
| 789 | } |
||
| 790 | |||
| 791 | /** |
||
| 792 | * Set object data from a request. |
||
| 793 | * |
||
| 794 | * @param \WC_Product $object Product object. |
||
| 795 | * @param \WP_REST_Request $request Request object. |
||
| 796 | */ |
||
| 797 | protected static function set_object_data( &$object, $request ) { |
||
| 798 | $props_to_set = [ |
||
| 799 | 'name', |
||
| 800 | 'sku', |
||
| 801 | 'description', |
||
| 802 | 'short_description', |
||
| 803 | 'slug', |
||
| 804 | 'menu_order', |
||
| 805 | 'reviews_allowed', |
||
| 806 | 'virtual', |
||
| 807 | 'tax_status', |
||
| 808 | 'tax_class', |
||
| 809 | 'catalog_visibility', |
||
| 810 | 'purchase_note', |
||
| 811 | 'status', |
||
| 812 | 'featured', |
||
| 813 | 'regular_price', |
||
| 814 | 'sale_price', |
||
| 815 | 'date_on_sale_from', |
||
| 816 | 'date_on_sale_from_gmt', |
||
| 817 | 'date_on_sale_to', |
||
| 818 | 'date_on_sale_to_gmt', |
||
| 819 | 'parent_id', |
||
| 820 | 'sold_individually', |
||
| 821 | 'manage_stock', |
||
| 822 | 'backorders', |
||
| 823 | 'stock_status', |
||
| 824 | 'stock_quantity', |
||
| 825 | 'downloadable', |
||
| 826 | 'button_text', |
||
| 827 | 'download_limit', |
||
| 828 | 'download_expiry', |
||
| 829 | ]; |
||
| 830 | |||
| 831 | foreach ( $props_to_set as $prop ) { |
||
| 832 | if ( isset( $request[ $prop ] ) && is_callable( array( $object, "set_$prop" ) ) ) { |
||
| 833 | $object->{"set_$prop"}( $request[ $prop ] ); |
||
| 834 | } |
||
| 835 | } |
||
| 836 | |||
| 837 | if ( isset( $request['external_url'] ) && is_callable( array( $object, 'set_product_url' ) ) ) { |
||
| 838 | $object->set_product_url( $request['external_url'] ); |
||
| 839 | } |
||
| 840 | |||
| 841 | if ( ! empty( $request['date_created'] ) ) { |
||
| 842 | $date = rest_parse_date( $request['date_created'] ); |
||
| 843 | |||
| 844 | if ( $date ) { |
||
| 845 | $object->set_date_created( $date ); |
||
| 846 | } |
||
| 847 | } |
||
| 848 | |||
| 849 | if ( ! empty( $request['date_created_gmt'] ) ) { |
||
| 850 | $date = rest_parse_date( $request['date_created_gmt'], true ); |
||
| 851 | |||
| 852 | if ( $date ) { |
||
| 853 | $object->set_date_created( $date ); |
||
| 854 | } |
||
| 855 | } |
||
| 856 | |||
| 857 | if ( isset( $request['upsell_ids'] ) ) { |
||
| 858 | $object->set_upsell_ids( wp_parse_id_list( $request['upsell_ids'] ) ); |
||
| 859 | } |
||
| 860 | |||
| 861 | if ( isset( $request['cross_sell_ids'] ) ) { |
||
| 862 | $object->set_cross_sell_ids( wp_parse_id_list( $request['cross_sell_ids'] ) ); |
||
| 863 | } |
||
| 864 | |||
| 865 | // Set children for a grouped product. |
||
| 866 | if ( $object->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { |
||
| 867 | $object->set_children( $request['grouped_products'] ); |
||
| 868 | } |
||
| 869 | |||
| 870 | // Allow set meta_data. |
||
| 871 | if ( isset( $request['meta_data'] ) ) { |
||
| 872 | foreach ( $request['meta_data'] as $meta ) { |
||
| 873 | $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); |
||
| 874 | } |
||
| 875 | } |
||
| 876 | |||
| 877 | // Save default attributes for variable products. |
||
| 878 | if ( $object->is_type( 'variable' ) && isset( $request['default_attributes'] ) ) { |
||
| 879 | self::set_default_attributes( $object, $request['default_attributes'] ); |
||
| 880 | } |
||
| 881 | |||
| 882 | // Check for featured/gallery images, upload it and set it. |
||
| 883 | if ( isset( $request['images'] ) ) { |
||
| 884 | self::set_images( $object, $request['images'] ); |
||
| 885 | } |
||
| 886 | |||
| 887 | // Product categories. |
||
| 888 | if ( isset( $request['categories'] ) ) { |
||
| 889 | self::set_taxonomy_terms( $object, $request['categories'] ); |
||
| 890 | } |
||
| 891 | |||
| 892 | // Product tags. |
||
| 893 | if ( isset( $request['tags'] ) ) { |
||
| 894 | self::set_taxonomy_terms( $object, $request['tags'], 'tag' ); |
||
| 895 | } |
||
| 896 | |||
| 897 | // Downloadable files. |
||
| 898 | if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { |
||
| 899 | self::set_downloadable_files( $object, $request['downloads'] ); |
||
| 900 | } |
||
| 901 | |||
| 902 | if ( isset( $request['attributes'] ) ) { |
||
| 903 | self::set_attributes( $object, $request['attributes'] ); |
||
| 904 | } |
||
| 905 | |||
| 906 | self::set_shipping_data( $object, $request ); |
||
| 907 | |||
| 908 | return $object; |
||
| 909 | } |
||
| 910 | |||
| 911 | /** |
||
| 912 | * Get the downloads for a product or product variation. |
||
| 913 | * |
||
| 914 | * @param \WC_Product|\WC_Product_Variation $object Product instance. |
||
| 915 | * |
||
| 916 | * @return array |
||
| 917 | */ |
||
| 918 | protected static function get_downloads( $object ) { |
||
| 919 | $downloads = array(); |
||
| 920 | |||
| 921 | if ( $object->is_downloadable() ) { |
||
| 922 | foreach ( $object->get_downloads() as $file_id => $file ) { |
||
| 923 | $downloads[] = array( |
||
| 924 | 'id' => $file_id, // MD5 hash. |
||
| 925 | 'name' => $file['name'], |
||
| 926 | 'file' => $file['file'], |
||
| 927 | ); |
||
| 928 | } |
||
| 929 | } |
||
| 930 | |||
| 931 | return $downloads; |
||
| 932 | } |
||
| 933 | |||
| 934 | /** |
||
| 935 | * Get taxonomy terms. |
||
| 936 | * |
||
| 937 | * @param \WC_Product $object Product instance. |
||
| 938 | * @param string $taxonomy Taxonomy slug. |
||
| 939 | * |
||
| 940 | * @return array |
||
| 941 | */ |
||
| 942 | protected static function get_taxonomy_terms( $object, $taxonomy = 'cat' ) { |
||
| 943 | $terms = array(); |
||
| 944 | |||
| 945 | foreach ( wc_get_object_terms( $object->get_id(), 'product_' . $taxonomy ) as $term ) { |
||
| 946 | $terms[] = array( |
||
| 947 | 'id' => $term->term_id, |
||
| 948 | 'name' => $term->name, |
||
| 949 | 'slug' => $term->slug, |
||
| 950 | ); |
||
| 951 | } |
||
| 952 | |||
| 953 | return $terms; |
||
| 954 | } |
||
| 955 | |||
| 956 | /** |
||
| 957 | * Get the images for a product or product variation. |
||
| 958 | * |
||
| 959 | * @param \WC_Product|\WC_Product_Variation $object Product instance. |
||
| 960 | * @return array |
||
| 961 | */ |
||
| 962 | protected static function get_images( $object ) { |
||
| 963 | $images = array(); |
||
| 964 | $attachment_ids = array(); |
||
| 965 | |||
| 966 | // Add featured image. |
||
| 967 | if ( $object->get_image_id() ) { |
||
| 968 | $attachment_ids[] = $object->get_image_id(); |
||
| 969 | } |
||
| 970 | |||
| 971 | // Add gallery images. |
||
| 972 | $attachment_ids = array_merge( $attachment_ids, $object->get_gallery_image_ids() ); |
||
| 973 | |||
| 974 | // Build image data. |
||
| 975 | foreach ( $attachment_ids as $attachment_id ) { |
||
| 976 | $attachment_post = get_post( $attachment_id ); |
||
| 977 | if ( is_null( $attachment_post ) ) { |
||
| 978 | continue; |
||
| 979 | } |
||
| 980 | |||
| 981 | $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); |
||
| 982 | if ( ! is_array( $attachment ) ) { |
||
| 983 | continue; |
||
| 984 | } |
||
| 985 | |||
| 986 | $images[] = array( |
||
| 987 | 'id' => (int) $attachment_id, |
||
| 988 | 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), |
||
| 989 | 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), |
||
| 990 | 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), |
||
| 991 | 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), |
||
| 992 | 'src' => current( $attachment ), |
||
| 993 | 'name' => get_the_title( $attachment_id ), |
||
| 994 | 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), |
||
| 995 | ); |
||
| 996 | } |
||
| 997 | |||
| 998 | return $images; |
||
| 999 | } |
||
| 1000 | |||
| 1001 | /** |
||
| 1002 | * Get product attribute taxonomy name. |
||
| 1003 | * |
||
| 1004 | * @param string $slug Taxonomy name. |
||
| 1005 | * @param \WC_Product $object Product data. |
||
| 1006 | * |
||
| 1007 | * @since 3.0.0 |
||
| 1008 | * @return string |
||
| 1009 | */ |
||
| 1010 | protected static function get_attribute_taxonomy_name( $slug, $object ) { |
||
| 1011 | // Format slug so it matches attributes of the product. |
||
| 1012 | $slug = wc_attribute_taxonomy_slug( $slug ); |
||
| 1013 | $attributes = $object->get_attributes(); |
||
| 1014 | $attribute = false; |
||
| 1015 | |||
| 1016 | // pa_ attributes. |
||
| 1017 | if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { |
||
| 1018 | $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; |
||
| 1019 | } elseif ( isset( $attributes[ $slug ] ) ) { |
||
| 1020 | $attribute = $attributes[ $slug ]; |
||
| 1021 | } |
||
| 1022 | |||
| 1023 | if ( ! $attribute ) { |
||
| 1024 | return $slug; |
||
| 1025 | } |
||
| 1026 | |||
| 1027 | // Taxonomy attribute name. |
||
| 1028 | if ( $attribute->is_taxonomy() ) { |
||
| 1029 | $taxonomy = $attribute->get_taxonomy_object(); |
||
| 1030 | return $taxonomy->attribute_label; |
||
| 1031 | } |
||
| 1032 | |||
| 1033 | // Custom product attribute name. |
||
| 1034 | return $attribute->get_name(); |
||
| 1035 | } |
||
| 1036 | |||
| 1037 | /** |
||
| 1038 | * Get default attributes. |
||
| 1039 | * |
||
| 1040 | * @param \WC_Product $object Product instance. |
||
| 1041 | * |
||
| 1042 | * @return array |
||
| 1043 | */ |
||
| 1044 | protected static function get_default_attributes( $object ) { |
||
| 1045 | $default = array(); |
||
| 1046 | |||
| 1047 | if ( $object->is_type( 'variable' ) ) { |
||
| 1048 | foreach ( array_filter( (array) $object->get_default_attributes(), 'strlen' ) as $key => $value ) { |
||
| 1049 | if ( 0 === strpos( $key, 'pa_' ) ) { |
||
| 1050 | $default[] = array( |
||
| 1051 | 'id' => wc_attribute_taxonomy_id_by_name( $key ), |
||
| 1052 | 'name' => self::get_attribute_taxonomy_name( $key, $object ), |
||
| 1053 | 'option' => $value, |
||
| 1054 | ); |
||
| 1055 | } else { |
||
| 1056 | $default[] = array( |
||
| 1057 | 'id' => 0, |
||
| 1058 | 'name' => self::get_attribute_taxonomy_name( $key, $object ), |
||
| 1059 | 'option' => $value, |
||
| 1060 | ); |
||
| 1061 | } |
||
| 1062 | } |
||
| 1063 | } |
||
| 1064 | |||
| 1065 | return $default; |
||
| 1066 | } |
||
| 1067 | |||
| 1068 | /** |
||
| 1069 | * Get attribute options. |
||
| 1070 | * |
||
| 1071 | * @param int $object_id Product ID. |
||
| 1072 | * @param array $attribute Attribute data. |
||
| 1073 | * |
||
| 1074 | * @return array |
||
| 1075 | */ |
||
| 1076 | protected static function get_attribute_options( $object_id, $attribute ) { |
||
| 1077 | if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { |
||
| 1078 | return wc_get_product_terms( |
||
| 1079 | $object_id, |
||
| 1080 | $attribute['name'], |
||
| 1081 | array( |
||
| 1082 | 'fields' => 'names', |
||
| 1083 | ) |
||
| 1084 | ); |
||
| 1085 | } elseif ( isset( $attribute['value'] ) ) { |
||
| 1086 | return array_map( 'trim', explode( '|', $attribute['value'] ) ); |
||
| 1087 | } |
||
| 1088 | |||
| 1089 | return array(); |
||
| 1090 | } |
||
| 1091 | |||
| 1092 | /** |
||
| 1093 | * Get the attributes for a product or product variation. |
||
| 1094 | * |
||
| 1095 | * @param \WC_Product|\WC_Product_Variation $object Product instance. |
||
| 1096 | * |
||
| 1097 | * @return array |
||
| 1098 | */ |
||
| 1099 | protected static function get_attributes( $object ) { |
||
| 1100 | $attributes = array(); |
||
| 1101 | |||
| 1102 | if ( $object->is_type( 'variation' ) ) { |
||
| 1103 | $_product = wc_get_product( $object->get_parent_id() ); |
||
| 1104 | foreach ( $object->get_variation_attributes() as $attribute_name => $attribute ) { |
||
| 1105 | $name = str_replace( 'attribute_', '', $attribute_name ); |
||
| 1106 | |||
| 1107 | if ( empty( $attribute ) && '0' !== $attribute ) { |
||
| 1108 | continue; |
||
| 1109 | } |
||
| 1110 | |||
| 1111 | // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. |
||
| 1112 | if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { |
||
| 1113 | $option_term = get_term_by( 'slug', $attribute, $name ); |
||
| 1114 | $attributes[] = array( |
||
| 1115 | 'id' => wc_attribute_taxonomy_id_by_name( $name ), |
||
| 1116 | 'name' => self::get_attribute_taxonomy_name( $name, $_product ), |
||
| 1117 | 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, |
||
| 1118 | ); |
||
| 1119 | } else { |
||
| 1120 | $attributes[] = array( |
||
| 1121 | 'id' => 0, |
||
| 1122 | 'name' => self::get_attribute_taxonomy_name( $name, $_product ), |
||
| 1123 | 'option' => $attribute, |
||
| 1124 | ); |
||
| 1125 | } |
||
| 1126 | } |
||
| 1127 | } else { |
||
| 1128 | foreach ( $object->get_attributes() as $attribute ) { |
||
| 1129 | $attributes[] = array( |
||
| 1130 | 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, |
||
| 1131 | 'name' => self::get_attribute_taxonomy_name( $attribute['name'], $object ), |
||
| 1132 | 'position' => (int) $attribute['position'], |
||
| 1133 | 'visible' => (bool) $attribute['is_visible'], |
||
| 1134 | 'variation' => (bool) $attribute['is_variation'], |
||
| 1135 | 'options' => self::get_attribute_options( $object->get_id(), $attribute ), |
||
| 1136 | ); |
||
| 1137 | } |
||
| 1138 | } |
||
| 1139 | |||
| 1140 | return $attributes; |
||
| 1141 | } |
||
| 1142 | |||
| 1143 | /** |
||
| 1144 | * Set product object's attributes. |
||
| 1145 | * |
||
| 1146 | * @param \WC_Product $object Product object. |
||
| 1147 | * @param array $raw_attributes Attribute data from request. |
||
| 1148 | */ |
||
| 1149 | protected static function set_attributes( &$object, $raw_attributes ) { |
||
| 1212 | } |
||
| 1213 | |||
| 1214 | /** |
||
| 1215 | * Set product images. |
||
| 1216 | * |
||
| 1217 | * @throws \WC_REST_Exception REST API exceptions. |
||
| 1218 | * |
||
| 1219 | * @param \WC_Product $object Product instance. |
||
| 1220 | * @param array $images Images data. |
||
| 1221 | */ |
||
| 1222 | protected static function set_images( &$object, $images ) { |
||
| 1223 | $images = is_array( $images ) ? array_filter( $images ) : array(); |
||
| 1224 | |||
| 1225 | if ( ! empty( $images ) ) { |
||
| 1226 | $gallery = array(); |
||
| 1227 | |||
| 1228 | foreach ( $images as $index => $image ) { |
||
| 1229 | $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; |
||
| 1230 | |||
| 1231 | if ( 0 === $attachment_id && isset( $image['src'] ) ) { |
||
| 1232 | $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); |
||
| 1233 | |||
| 1234 | if ( is_wp_error( $upload ) ) { |
||
| 1235 | if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), $images ) ) { |
||
| 1236 | throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); |
||
| 1237 | } else { |
||
| 1238 | continue; |
||
| 1239 | } |
||
| 1240 | } |
||
| 1241 | |||
| 1242 | $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $object->get_id() ); |
||
| 1243 | } |
||
| 1244 | |||
| 1245 | if ( ! wp_attachment_is_image( $attachment_id ) ) { |
||
| 1246 | /* translators: %s: image ID */ |
||
| 1247 | throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); |
||
| 1248 | } |
||
| 1249 | |||
| 1250 | $featured_image = $object->get_image_id(); |
||
| 1251 | |||
| 1252 | if ( 0 === $index ) { |
||
| 1253 | $object->set_image_id( $attachment_id ); |
||
| 1254 | } else { |
||
| 1255 | $gallery[] = $attachment_id; |
||
| 1256 | } |
||
| 1257 | |||
| 1258 | // Set the image alt if present. |
||
| 1259 | if ( ! empty( $image['alt'] ) ) { |
||
| 1260 | update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); |
||
| 1261 | } |
||
| 1262 | |||
| 1263 | // Set the image name if present. |
||
| 1264 | if ( ! empty( $image['name'] ) ) { |
||
| 1265 | wp_update_post( |
||
| 1266 | array( |
||
| 1267 | 'ID' => $attachment_id, |
||
| 1268 | 'post_title' => $image['name'], |
||
| 1269 | ) |
||
| 1270 | ); |
||
| 1271 | } |
||
| 1272 | } |
||
| 1273 | |||
| 1274 | $object->set_gallery_image_ids( $gallery ); |
||
| 1275 | } else { |
||
| 1276 | $object->set_image_id( '' ); |
||
| 1277 | $object->set_gallery_image_ids( array() ); |
||
| 1278 | } |
||
| 1279 | } |
||
| 1280 | |||
| 1281 | /** |
||
| 1282 | * Set product shipping data. |
||
| 1283 | * |
||
| 1284 | * @param \WC_Product $object Product instance. |
||
| 1285 | * @param array $data Shipping data. |
||
| 1286 | */ |
||
| 1287 | protected static function set_shipping_data( &$object, $data ) { |
||
| 1288 | if ( $object->get_virtual() ) { |
||
| 1289 | $object->set_weight( '' ); |
||
| 1290 | $object->set_height( '' ); |
||
| 1291 | $object->set_length( '' ); |
||
| 1292 | $object->set_width( '' ); |
||
| 1293 | } else { |
||
| 1294 | if ( isset( $data['weight'] ) ) { |
||
| 1295 | $object->set_weight( $data['weight'] ); |
||
| 1296 | } |
||
| 1297 | |||
| 1298 | // Height. |
||
| 1299 | if ( isset( $data['dimensions']['height'] ) ) { |
||
| 1300 | $object->set_height( $data['dimensions']['height'] ); |
||
| 1301 | } |
||
| 1302 | |||
| 1303 | // Width. |
||
| 1304 | if ( isset( $data['dimensions']['width'] ) ) { |
||
| 1305 | $object->set_width( $data['dimensions']['width'] ); |
||
| 1306 | } |
||
| 1307 | |||
| 1308 | // Length. |
||
| 1309 | if ( isset( $data['dimensions']['length'] ) ) { |
||
| 1310 | $object->set_length( $data['dimensions']['length'] ); |
||
| 1311 | } |
||
| 1312 | } |
||
| 1313 | |||
| 1314 | // Shipping class. |
||
| 1315 | if ( isset( $data['shipping_class'] ) ) { |
||
| 1316 | $data_store = $object->get_data_store(); |
||
| 1317 | $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); |
||
| 1318 | $object->set_shipping_class_id( $shipping_class_id ); |
||
| 1319 | } |
||
| 1320 | } |
||
| 1321 | |||
| 1322 | /** |
||
| 1323 | * Save downloadable files. |
||
| 1324 | * |
||
| 1325 | * @param \WC_Product $object Product instance. |
||
| 1326 | * @param array $downloads Downloads data. |
||
| 1327 | */ |
||
| 1328 | protected static function set_downloadable_files( &$object, $downloads ) { |
||
| 1342 | } |
||
| 1343 | |||
| 1344 | /** |
||
| 1345 | * Save taxonomy terms. |
||
| 1346 | * |
||
| 1347 | * @param \WC_Product $object Product instance. |
||
| 1348 | * @param array $terms Terms data. |
||
| 1349 | * @param string $taxonomy Taxonomy name. |
||
| 1350 | */ |
||
| 1351 | protected static function set_taxonomy_terms( &$object, $terms, $taxonomy = 'cat' ) { |
||
| 1352 | $term_ids = wp_list_pluck( $terms, 'id' ); |
||
| 1353 | |||
| 1354 | if ( 'cat' === $taxonomy ) { |
||
| 1355 | $object->set_category_ids( $term_ids ); |
||
| 1356 | } elseif ( 'tag' === $taxonomy ) { |
||
| 1357 | $object->set_tag_ids( $term_ids ); |
||
| 1358 | } |
||
| 1359 | } |
||
| 1360 | |||
| 1361 | /** |
||
| 1362 | * Save default attributes. |
||
| 1363 | * |
||
| 1364 | * @param \WC_Product $object Product instance. |
||
| 1365 | * @param array $raw_default_attributes Default attributes. |
||
| 1366 | */ |
||
| 1367 | protected static function set_default_attributes( &$object, $raw_default_attributes ) { |
||
| 1412 | } |
||
| 1413 | } |
||
| 1414 |