Merge pull request #22613 from woocommerce/performance/set-props

Performance: `set_props`
This commit is contained in:
Claudiu Lodromanean 2019-02-06 10:02:54 -08:00 committed by GitHub
commit 2d2d7a7053
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 109 additions and 94 deletions

View File

@ -220,7 +220,7 @@ abstract class WC_Data {
* @return string Data in JSON format.
*/
public function __toString() {
return json_encode( $this->get_data() );
return wp_json_encode( $this->get_data() );
}
/**
@ -283,7 +283,7 @@ abstract class WC_Data {
* @return bool true if it's an internal key, false otherwise
*/
protected function is_internal_meta_key( $key ) {
$internal_meta_key = ! empty( $key ) && $this->data_store && in_array( $key, $this->data_store->get_internal_meta_keys() );
$internal_meta_key = ! empty( $key ) && $this->data_store && in_array( $key, $this->data_store->get_internal_meta_keys(), true );
if ( ! $internal_meta_key ) {
return false;
@ -320,7 +320,7 @@ abstract class WC_Data {
$this->maybe_read_meta_data();
$meta_data = $this->get_meta_data();
$array_keys = array_keys( wp_list_pluck( $meta_data, 'key' ), $key );
$array_keys = array_keys( wp_list_pluck( $meta_data, 'key' ), $key, true );
$value = $single ? '' : array();
if ( ! empty( $array_keys ) ) {
@ -349,7 +349,7 @@ abstract class WC_Data {
public function meta_exists( $key = '' ) {
$this->maybe_read_meta_data();
$array_keys = wp_list_pluck( $this->get_meta_data(), 'key' );
return in_array( $key, $array_keys );
return in_array( $key, $array_keys, true );
}
/**
@ -364,11 +364,13 @@ abstract class WC_Data {
foreach ( $data as $meta ) {
$meta = (array) $meta;
if ( isset( $meta['key'], $meta['value'], $meta['id'] ) ) {
$this->meta_data[] = new WC_Meta_Data( array(
'id' => $meta['id'],
'key' => $meta['key'],
'value' => $meta['value'],
) );
$this->meta_data[] = new WC_Meta_Data(
array(
'id' => $meta['id'],
'key' => $meta['key'],
'value' => $meta['value'],
)
);
}
}
}
@ -379,9 +381,9 @@ abstract class WC_Data {
*
* @since 2.6.0
*
* @param string $key Meta key.
* @param string|array $value Meta value.
* @param bool $unique Should this be a unique key?.
* @param string $key Meta key.
* @param string|array $value Meta value.
* @param bool $unique Should this be a unique key?.
*/
public function add_meta_data( $key, $value, $unique = false ) {
if ( $this->is_internal_meta_key( $key ) ) {
@ -396,10 +398,12 @@ abstract class WC_Data {
if ( $unique ) {
$this->delete_meta_data( $key );
}
$this->meta_data[] = new WC_Meta_Data( array(
'key' => $key,
'value' => $value,
) );
$this->meta_data[] = new WC_Meta_Data(
array(
'key' => $key,
'value' => $value,
)
);
}
/**
@ -462,7 +466,7 @@ abstract class WC_Data {
*/
public function delete_meta_data( $key ) {
$this->maybe_read_meta_data();
$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key );
$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key, true );
if ( $array_keys ) {
foreach ( $array_keys as $array_key ) {
@ -479,7 +483,7 @@ abstract class WC_Data {
*/
public function delete_meta_data_by_mid( $mid ) {
$this->maybe_read_meta_data();
$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), $mid );
$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), (int) $mid, true );
if ( $array_keys ) {
foreach ( $array_keys as $array_key ) {
@ -507,8 +511,8 @@ abstract class WC_Data {
* @param bool $force_read True to force a new DB read (and update cache).
*/
public function read_meta_data( $force_read = false ) {
$this->meta_data = array();
$cache_loaded = false;
$this->meta_data = array();
$cache_loaded = false;
if ( ! $this->get_id() ) {
return;
@ -533,11 +537,13 @@ abstract class WC_Data {
$raw_meta_data = $cache_loaded ? $cached_meta : $this->data_store->read_meta( $this );
if ( $raw_meta_data ) {
foreach ( $raw_meta_data as $meta ) {
$this->meta_data[] = new WC_Meta_Data( array(
'id' => (int) $meta->meta_id,
'key' => $meta->meta_key,
'value' => maybe_unserialize( $meta->meta_value ),
) );
$this->meta_data[] = new WC_Meta_Data(
array(
'id' => (int) $meta->meta_id,
'key' => $meta->meta_key,
'value' => maybe_unserialize( $meta->meta_value ),
)
);
}
if ( ! $cache_loaded && ! empty( $this->cache_group ) ) {
@ -593,8 +599,8 @@ abstract class WC_Data {
* @since 3.0.0
*/
public function set_defaults() {
$this->data = $this->default_data;
$this->changes = array();
$this->data = $this->default_data;
$this->changes = array();
$this->set_object_read( false );
}
@ -630,27 +636,30 @@ abstract class WC_Data {
* @return bool|WP_Error
*/
public function set_props( $props, $context = 'set' ) {
$errors = new WP_Error();
$errors = false;
foreach ( $props as $prop => $value ) {
try {
if ( 'meta_data' === $prop ) {
/**
* Checks if the prop being set is allowed, and the value is not null.
*/
if ( is_null( $value ) || in_array( $prop, array( 'prop', 'date_prop', 'meta_data' ), true ) ) {
continue;
}
$setter = "set_$prop";
if ( ! is_null( $value ) && is_callable( array( $this, $setter ) ) ) {
$reflection = new ReflectionMethod( $this, $setter );
if ( $reflection->isPublic() ) {
$this->{$setter}( $value );
}
if ( is_callable( array( $this, $setter ) ) ) {
$this->{$setter}( $value );
}
} catch ( WC_Data_Exception $e ) {
if ( ! $errors ) {
$errors = new WP_Error();
}
$errors->add( $e->getErrorCode(), $e->getMessage() );
}
}
return count( $errors->get_error_codes() ) ? $errors : true;
return $errors && count( $errors->get_error_codes() ) ? $errors : true;
}
/**
@ -757,7 +766,7 @@ abstract class WC_Data {
} else {
$timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $value ) ) ) );
}
$datetime = new WC_DateTime( "@{$timestamp}", new DateTimeZone( 'UTC' ) );
$datetime = new WC_DateTime( "@{$timestamp}", new DateTimeZone( 'UTC' ) );
}
// Set local timezone or offset.

View File

@ -297,66 +297,72 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
* @since 3.0.0
*/
protected function read_product_data( &$product ) {
$id = $product->get_id();
$review_count = get_post_meta( $id, '_wc_review_count', true );
$rating_counts = get_post_meta( $id, '_wc_rating_count', true );
$average_rating = get_post_meta( $id, '_wc_average_rating', true );
if ( '' === $review_count ) {
WC_Comments::get_review_count_for_product( $product );
} else {
$product->set_review_count( $review_count );
}
if ( '' === $rating_counts ) {
WC_Comments::get_rating_counts_for_product( $product );
} else {
$product->set_rating_counts( $rating_counts );
}
if ( '' === $average_rating ) {
WC_Comments::get_average_rating_for_product( $product );
} else {
$product->set_average_rating( $average_rating );
}
$product->set_props(
array(
'sku' => get_post_meta( $id, '_sku', true ),
'regular_price' => get_post_meta( $id, '_regular_price', true ),
'sale_price' => get_post_meta( $id, '_sale_price', true ),
'price' => get_post_meta( $id, '_price', true ),
'date_on_sale_from' => get_post_meta( $id, '_sale_price_dates_from', true ),
'date_on_sale_to' => get_post_meta( $id, '_sale_price_dates_to', true ),
'total_sales' => get_post_meta( $id, 'total_sales', true ),
'tax_status' => get_post_meta( $id, '_tax_status', true ),
'tax_class' => get_post_meta( $id, '_tax_class', true ),
'manage_stock' => get_post_meta( $id, '_manage_stock', true ),
'stock_quantity' => get_post_meta( $id, '_stock', true ),
'stock_status' => get_post_meta( $id, '_stock_status', true ),
'backorders' => get_post_meta( $id, '_backorders', true ),
'low_stock_amount' => get_post_meta( $id, '_low_stock_amount', true ),
'sold_individually' => get_post_meta( $id, '_sold_individually', true ),
'weight' => get_post_meta( $id, '_weight', true ),
'length' => get_post_meta( $id, '_length', true ),
'width' => get_post_meta( $id, '_width', true ),
'height' => get_post_meta( $id, '_height', true ),
'upsell_ids' => get_post_meta( $id, '_upsell_ids', true ),
'cross_sell_ids' => get_post_meta( $id, '_crosssell_ids', true ),
'purchase_note' => get_post_meta( $id, '_purchase_note', true ),
'default_attributes' => get_post_meta( $id, '_default_attributes', true ),
'category_ids' => $this->get_term_ids( $product, 'product_cat' ),
'tag_ids' => $this->get_term_ids( $product, 'product_tag' ),
'shipping_class_id' => current( $this->get_term_ids( $product, 'product_shipping_class' ) ),
'virtual' => get_post_meta( $id, '_virtual', true ),
'downloadable' => get_post_meta( $id, '_downloadable', true ),
'gallery_image_ids' => array_filter( explode( ',', get_post_meta( $id, '_product_image_gallery', true ) ) ),
'download_limit' => get_post_meta( $id, '_download_limit', true ),
'download_expiry' => get_post_meta( $id, '_download_expiry', true ),
'image_id' => get_post_thumbnail_id( $id ),
)
$id = $product->get_id();
$post_meta_values = get_post_meta( $id );
$meta_key_to_props = array(
'_sku' => 'sku',
'_regular_price' => 'regular_price',
'_sale_price' => 'sale_price',
'_price' => 'price',
'_sale_price_dates_from' => 'date_on_sale_from',
'_sale_price_dates_to' => 'date_on_sale_to',
'total_sales' => 'total_sales',
'_tax_status' => 'tax_status',
'_tax_class' => 'tax_class',
'_manage_stock' => 'manage_stock',
'_backorders' => 'backorders',
'_low_stock_amount' => 'low_stock_amount',
'_sold_individually' => 'sold_individually',
'_weight' => 'weight',
'_length' => 'length',
'_width' => 'width',
'_height' => 'height',
'_upsell_ids' => 'upsell_ids',
'_crosssell_ids' => 'cross_sell_ids',
'_purchase_note' => 'purchase_note',
'_default_attributes' => 'default_attributes',
'_virtual' => 'virtual',
'_downloadable' => 'downloadable',
'_download_limit' => 'download_limit',
'_download_expiry' => 'download_expiry',
'_thumbnail_id' => 'image_id',
'_stock' => 'stock_quantity',
'_stock_status' => 'stock_status',
'_wc_average_rating' => 'average_rating',
'_wc_rating_count' => 'rating_counts',
'_wc_review_count' => 'review_count',
'_product_image_gallery' => 'gallery_image_ids',
);
$set_props = array();
foreach ( $meta_key_to_props as $meta_key => $prop ) {
$meta_value = isset( $post_meta_values[ $meta_key ][0] ) ? $post_meta_values[ $meta_key ][0] : '';
$set_props[ $prop ] = maybe_unserialize( $meta_value ); // get_post_meta only unserializes single values.
}
$set_props['category_ids'] = $this->get_term_ids( $product, 'product_cat' );
$set_props['tag_ids'] = $this->get_term_ids( $product, 'product_tag' );
$set_props['shipping_class_id'] = current( $this->get_term_ids( $product, 'product_shipping_class' ) );
$set_props['gallery_image_ids'] = array_filter( explode( ',', $set_props['gallery_image_ids'] ) );
if ( '' === $set_props['review_count'] ) {
unset( $set_props['review_count'] );
WC_Comments::get_review_count_for_product( $product );
}
if ( '' === $set_props['rating_counts'] ) {
unset( $set_props['rating_counts'] );
WC_Comments::get_rating_counts_for_product( $product );
}
if ( '' === $set_props['average_rating'] ) {
unset( $set_props['average_rating'] );
WC_Comments::get_average_rating_for_product( $product );
}
$product->set_props( $set_props );
// Handle sale dates on the fly in case of missed cron schedule.
if ( $product->is_type( 'simple' ) && $product->is_on_sale( 'edit' ) && $product->get_sale_price( 'edit' ) !== $product->get_price( 'edit' ) ) {
update_post_meta( $product->get_id(), '_price', $product->get_sale_price( 'edit' ) );