Merge pull request #12109 from woocommerce/product-crud-update-fields

[Product CRUD] Full Creation & Updating (Abstract)
This commit is contained in:
Mike Jolley 2016-10-18 16:57:50 +01:00 committed by GitHub
commit 2fb0dd50d5
3 changed files with 233 additions and 91 deletions

View File

@ -139,6 +139,27 @@ abstract class WC_Abstract_Legacy_Product extends WC_Data {
* @return int * @return int
*/ */
public function get_parent() { public function get_parent() {
_deprecated_function( 'WC_Product::get_parent', '2.7', 'WC_Product::get_parent_id' );
return apply_filters( 'woocommerce_product_parent', absint( $this->post->post_parent ), $this ); return apply_filters( 'woocommerce_product_parent', absint( $this->post->post_parent ), $this );
} }
/**
* Returns the upsell product ids.
*
* @return array
*/
public function get_upsells() {
_deprecated_function( 'WC_Product::get_upsells', '2.7', 'WC_Product::get_upsell_ids' );
return apply_filters( 'woocommerce_product_upsell_ids', (array) maybe_unserialize( $this->upsell_ids ), $this );
}
/**
* Returns the cross sell product ids.
*
* @return array
*/
public function get_cross_sells() {
_deprecated_function( 'WC_Product::get_cross_sells', '2.7', 'WC_Product::get_cross_sell_ids' );
return apply_filters( 'woocommerce_product_crosssell_ids', (array) maybe_unserialize( $this->crosssell_ids ), $this );
}
} }

View File

@ -22,17 +22,16 @@ include_once( 'abstract-wc-legacy-product.php' );
class WC_Product extends WC_Abstract_Legacy_Product { class WC_Product extends WC_Abstract_Legacy_Product {
/** /**
* Stores customer data. * Stores product data.
* *
* @var array * @var array
*/ */
protected $data = array( protected $data = array(
'name' => '', 'name' => '',
'slug' => '', 'slug' => '',
//'permalink' => '',
'date_created' => '', 'date_created' => '',
'date_modified' => '', 'date_modified' => '',
'status' => '', 'status' => 'publish',
'featured' => false, 'featured' => false,
'catalog_visibility' => 'hidden', 'catalog_visibility' => 'hidden',
'description' => '', 'description' => '',
@ -87,6 +86,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @param int|WC_Product|object $product Product to init. * @param int|WC_Product|object $product Product to init.
*/ */
public function __construct( $product = 0 ) { public function __construct( $product = 0 ) {
parent::__construct( $product );
if ( is_numeric( $product ) && $product > 0 ) { if ( is_numeric( $product ) && $product > 0 ) {
$this->read( $product ); $this->read( $product );
} elseif ( $product instanceof self ) { } elseif ( $product instanceof self ) {
@ -96,6 +96,14 @@ class WC_Product extends WC_Abstract_Legacy_Product {
} }
} }
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
|
| Methods for getting data from the product object.
*/
/** /**
* Get internal type. * Get internal type.
* @since 2.7.0 * @since 2.7.0
@ -113,14 +121,6 @@ class WC_Product extends WC_Abstract_Legacy_Product {
return get_permalink( $this->get_id() ); return get_permalink( $this->get_id() );
} }
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
|
| Methods for getting data from the product object.
*/
/** /**
* Get product name. * Get product name.
* *
@ -442,14 +442,16 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @return array * @return array
*/ */
public function get_attributes() { public function get_attributes() {
$attributes = $this->data['product_attributes']; $attributes = $this->data['attributes'];
$taxonomies = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_name' ); $taxonomies = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_name' );
// Check for any attributes which have been removed globally // Check for any attributes which have been removed globally
foreach ( $attributes as $key => $attribute ) { if ( is_array( $attributes ) && count( $attributes ) > 0 ) {
if ( $attribute['is_taxonomy'] ) { foreach ( $attributes as $key => $attribute ) {
if ( ! in_array( substr( $attribute['name'], 3 ), $taxonomies ) ) { if ( $attribute['is_taxonomy'] ) {
unset( $attributes[ $key ] ); if ( ! in_array( substr( $attribute['name'], 3 ), $taxonomies ) ) {
unset( $attributes[ $key ] );
}
} }
} }
} }
@ -477,6 +479,30 @@ class WC_Product extends WC_Abstract_Legacy_Product {
return $this->data['menu_order']; return $this->data['menu_order'];
} }
/**
* Returns the product categories. @todo store in class and save?
*
* @param string $sep (default: ', ').
* @param string $before (default: '').
* @param string $after (default: '').
* @return string
*/
public function get_categories( $sep = ', ', $before = '', $after = '' ) {
return get_the_term_list( $this->get_id(), 'product_cat', $before, $sep, $after );
}
/**
* Returns the product tags. @todo store in class and save?
*
* @param string $sep (default: ', ').
* @param string $before (default: '').
* @param string $after (default: '').
* @return array
*/
public function get_tags( $sep = ', ', $before = '', $after = '' ) {
return get_the_term_list( $this->get_id(), 'product_tag', $before, $sep, $after );
}
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Setters | Setters
@ -835,13 +861,13 @@ class WC_Product extends WC_Abstract_Legacy_Product {
} }
/** /**
* Returns product attributes. * Set product attributes.
* *
* @since 2.7.0 * @since 2.7.0
* @param array $attributes List of product attributes. * @param array $attributes List of product attributes.
*/ */
public function set_attributes( $attributes ) { public function set_attributes( $attributes ) {
$this->data['product_attributes'] = $attributes; // @todo ensure unserialised, array, and filtered out empty values $this->data['attributes'] = $attributes; // @todo ensure unserialised, array, and filtered out empty values
} }
/** /**
@ -864,47 +890,6 @@ class WC_Product extends WC_Abstract_Legacy_Product {
$this->data['menu_order'] = intval( $menu_order ); $this->data['menu_order'] = intval( $menu_order );
} }
/**
* Returns the product categories. @todo store in class and save?
*
* @param string $sep (default: ', ').
* @param string $before (default: '').
* @param string $after (default: '').
* @return string
*/
public function get_categories( $sep = ', ', $before = '', $after = '' ) {
return get_the_term_list( $this->get_id(), 'product_cat', $before, $sep, $after );
}
/**
* Returns the product tags. @todo store in class and save?
*
* @param string $sep (default: ', ').
* @param string $before (default: '').
* @param string $after (default: '').
* @return array
*/
public function get_tags( $sep = ', ', $before = '', $after = '' ) {
return get_the_term_list( $this->get_id(), 'product_tag', $before, $sep, $after );
}
/** /**
* Set the product categories. @todo store in class and save? * Set the product categories. @todo store in class and save?
* *
@ -925,8 +910,6 @@ class WC_Product extends WC_Abstract_Legacy_Product {
$this->save_taxonomy_terms( $terms_id, 'tag' ); $this->save_taxonomy_terms( $terms_id, 'tag' );
} }
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| CRUD methods | CRUD methods
@ -961,7 +944,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
'type' => '', 'type' => '',
'status' => $post_object->post_status, 'status' => $post_object->post_status,
'featured' => get_post_meta( $id, '_featured', true ), 'featured' => get_post_meta( $id, '_featured', true ),
'catalog_visibility' => 'hidden', 'catalog_visibility' => get_post_meta( $id, '_visibility', true ),
'description' => $post_object->post_content, 'description' => $post_object->post_content,
'short_description' => $post_object->post_excerpt, 'short_description' => $post_object->post_excerpt,
'sku' => get_post_meta( $id, '_sku', true ), 'sku' => get_post_meta( $id, '_sku', true ),
@ -972,7 +955,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
'total_sales' => get_post_meta( $id, 'total_sales', true ), 'total_sales' => get_post_meta( $id, 'total_sales', true ),
'tax_status' => get_post_meta( $id, '_tax_status', true ), 'tax_status' => get_post_meta( $id, '_tax_status', true ),
'tax_class' => get_post_meta( $id, '_tax_class', true ), 'tax_class' => get_post_meta( $id, '_tax_class', true ),
'manage_stock' => 'no', 'manage_stock' => get_post_meta( $id, '_manage_stock', true ),
'stock_quantity' => get_post_meta( $id, '_stock', true ), 'stock_quantity' => get_post_meta( $id, '_stock', true ),
'stock_status' => get_post_meta( $id, '_stock_status', true ), 'stock_status' => get_post_meta( $id, '_stock_status', true ),
'backorders' => get_post_meta( $id, '_backorders', true ), 'backorders' => get_post_meta( $id, '_backorders', true ),
@ -1004,14 +987,17 @@ class WC_Product extends WC_Abstract_Legacy_Product {
$this->set_date_created( current_time( 'timestamp' ) ); $this->set_date_created( current_time( 'timestamp' ) );
$id = wp_insert_post( apply_filters( 'woocommerce_new_product_data', array( $id = wp_insert_post( apply_filters( 'woocommerce_new_product_data', array(
'post_type' => 'product', 'post_type' => 'product',
'post_status' => 'publish', 'post_status' => $this->get_status(),
'post_author' => get_current_user_id(), 'post_author' => get_current_user_id(),
'post_title' => $this->get_code(), 'post_title' => $this->get_name(),
'post_content' => '', 'post_content' => $this->get_description(),
'post_excerpt' => $this->get_description(), 'post_excerpt' => $this->get_short_description(),
'post_date' => date( 'Y-m-d H:i:s', $this->get_date_created() ), 'post_parent' => $this->get_parent_id(),
'post_date_gmt' => get_gmt_from_date( date( 'Y-m-d H:i:s', $this->get_date_created() ) ), 'comment_status' => $this->get_reviews_allowed(),
'menu_order' => $this->get_menu_order(),
'post_date' => date( 'Y-m-d H:i:s', $this->get_date_created() ),
'post_date_gmt' => get_gmt_from_date( date( 'Y-m-d H:i:s', $this->get_date_created() ) ),
) ), true ); ) ), true );
if ( $id ) { if ( $id ) {
@ -1028,7 +1014,20 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @since 2.7.0 * @since 2.7.0
*/ */
public function update() { public function update() {
$post_data = array(
'ID' => $this->get_id(),
'post_content' => $this->get_description(),
'post_excerpt' => $this->get_short_description(),
'post_title' => $this->get_name(),
'post_parent' => $this->get_parent_id(),
'comment_status' => $this->get_reviews_allowed(),
'post_status' => $this->get_status(),
'menu_order' => $this->get_menu_order(),
);
wp_update_post( $post_data );
$this->update_post_meta( $this->get_id() );
$this->save_meta_data();
do_action( 'woocommerce_update_product', $this->get_id() );
} }
/** /**
@ -1062,7 +1061,30 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @param int $id Object ID. * @param int $id Object ID.
*/ */
private function update_post_meta( $id ) { private function update_post_meta( $id ) {
// update_post_meta( $id, 'discount_type', $this->get_discount_type() ); update_post_meta( $id, '_featured', $this->get_featured() );
update_post_meta( $id, '_visibility', $this->get_catalog_visibility() );
update_post_meta( $id, '_sku', $this->get_sku() );
update_post_meta( $id, '_regular_price', $this->get_regular_price() );
update_post_meta( $id, '_sale_price', $this->get_sale_price() );
update_post_meta( $id, '_sale_price_dates_from', $this->get_date_on_sale_from() );
update_post_meta( $id, '_sale_price_dates_to', $this->get_date_on_sale_to() );
update_post_meta( $id, 'total_sales', $this->get_total_sales() );
update_post_meta( $id, '_tax_status', $this->get_tax_status() );
update_post_meta( $id, '_tax_class', $this->get_tax_class() );
update_post_meta( $id, '_manage_stock', $this->get_manage_stock() );
update_post_meta( $id, '_stock', $this->get_stock_quantity() );
update_post_meta( $id, '_stock_status', $this->get_stock_status() );
update_post_meta( $id, '_backorders', $this->get_backorders() );
update_post_meta( $id, '_sold_individually', $this->get_sold_individually() );
update_post_meta( $id, '_weight', $this->get_weight() );
update_post_meta( $id, '_length', $this->get_length() );
update_post_meta( $id, '_width', $this->get_width() );
update_post_meta( $id, '_height', $this->get_height() );
update_post_meta( $id, '_upsell_ids', $this->get_upsell_ids() );
update_post_meta( $id, '_crosssell_ids', $this->get_cross_sell_ids() );
update_post_meta( $id, '_purchase_note', $this->get_purchase_note() );
update_post_meta( $id, '_attributes', $this->get_attributes() );
update_post_meta( $id, '_default_attributes', $this->get_default_attributes() );
} }
/* /*
@ -2014,24 +2036,6 @@ class WC_Product extends WC_Abstract_Legacy_Product {
return apply_filters( 'woocommerce_product_review_count', $count, $this ); return apply_filters( 'woocommerce_product_review_count', $count, $this );
} }
/**
* Returns the upsell product ids.
*
* @return array
*/
public function get_upsells() {
return apply_filters( 'woocommerce_product_upsell_ids', (array) maybe_unserialize( $this->upsell_ids ), $this );
}
/**
* Returns the cross sell product ids.
*
* @return array
*/
public function get_cross_sells() {
return apply_filters( 'woocommerce_product_crosssell_ids', (array) maybe_unserialize( $this->crosssell_ids ), $this );
}
/** /**
* Returns the product shipping class. * Returns the product shipping class.
* *

View File

@ -0,0 +1,117 @@
<?php
/**
* CRUD Functions.
* @package WooCommerce\Tests\Product
* @since 2.7.0
*/
class WC_Tests_Product_CRUD extends WC_Unit_Test_Case {
/**
* Test creating a new product.
*
* @since 2.7.0
*/
function test_product_create() {
$product = new WC_Product;
$product->set_regular_price( 42 );
$product->set_name( 'My Product' );
$product->create();
$read_product = new WC_Product( $product->get_id() );
$this->assertEquals( '42', $read_product->get_regular_price() );
$this->assertEquals( 'My Product', $read_product->get_name() );
}
/**
* Test reading a product.
*
* @since 2.7.0
*/
function test_product_read() {
$product = WC_Helper_Product::create_simple_product();
$product = new WC_Product( $product->get_id() );
$this->assertEquals( '10', $product->get_regular_price() );
}
/**
* Test updating a product.
*
* @since 2.7.0
*/
function test_product_update() {
$product = WC_Helper_Product::create_simple_product();
$this->assertEquals( '10', $product->get_regular_price() );
$product->set_regular_price( 15 );
$product->save();
// Reread from database
$product = new WC_Product( $product->get_id() );
$this->assertEquals( '15', $product->get_regular_price() );
}
/**
* Test deleting a product.
*
* @since 2.7.0
*/
function test_product_delete() {
$product = WC_Helper_Product::create_simple_product();
$product->delete();
$this->assertEquals( 0, $product->get_id() );
}
/**
* Test product setters and getters
* @todo needs tests for tags, categories, and attributes
* @since 2.7.0
*/
public function test_product_getters_and_setters() {
$getters_and_setters = array(
'name' => 'Test',
'slug' => 'test',
'status' => 'publish',
'catalog_visibility' => 'search',
'featured' => false,
'description' => 'Hello world',
'short_description' => 'hello',
'sku' => 'TEST SKU',
'regular_price' => 15.00,
'sale_price' => 10.00,
'date_on_sale_from' => '1475798400',
'date_on_sale_to' => '1477267200',
'total_sales' => 20,
'tax_status' => 'none',
'tax_class' => '',
'manage_stock' => true,
'stock_quantity' => 10,
'stock_status' => 'instock',
'backorders' => 'notify',
'sold_individually' => false,
'weight' => 100,
'length' => 10,
'width' => 10,
'height' => 10,
'upsell_ids' => array( 2, 3 ),
'cross_sell_ids' => array( 4, 5 ),
'parent_id' => 0,
'reviews_allowed' => true,
'default_attributes' => array(),
'purchase_note' => 'A note',
'menu_order' => 2,
);
$product = new WC_Product;
foreach ( $getters_and_setters as $function => $value ) {
$product->{"set_{$function}"}( $value );
}
$product->create();
$product = new WC_Product_Simple( $product->get_id() );
foreach ( $getters_and_setters as $function => $value ) {
$this->assertEquals( $value, $product->{"get_{$function}"}(), $function );
}
}
}