Skip to content

Commit

Permalink
Improving variant support
Browse files Browse the repository at this point in the history
- Reading sync settings from variant's parents instead of the variant itself
- Adding a bulk action and supporting JS that changes simple products into product variants
  • Loading branch information
aldavigdis committed Jul 5, 2024
1 parent 03b26ce commit a98da51
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 16 deletions.
48 changes: 48 additions & 0 deletions js/products.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class NineteenEightyWooProducts {
static actionSelect() {
return document.getElementById( 'bulk-action-selector-top' );
}

static addProductIdInputToActions() {
let actionsContainer = document.querySelector( '#posts-filter .bulkactions' );
let actionButton = document.getElementById( 'doaction' );
let productIdInput = document.createElement( 'input' );
let spacerTextNode = document.createTextNode( ' ' );

productIdInput.setAttribute( 'type', 'text' );
productIdInput.setAttribute( 'name', 'action_post_id' );
productIdInput.setAttribute( 'id', 'action_post_id_input' );
productIdInput.setAttribute( 'placeholder', 'Parent ID' );

actionsContainer.insertBefore( productIdInput, actionButton );
actionsContainer.insertBefore( spacerTextNode, actionButton );
}

static removeProductInputFromActions() {
let element = document.getElementById( 'action_post_id_input' );

if ( element !== null ) {
element.remove();
}
}

static selectMenuEvent( e ) {
if ( e.target.value == 'convert_to_variant' ) {
NineteenEightyWooProducts.addProductIdInputToActions();
} else {
NineteenEightyWooProducts.removeProductInputFromActions();
}
}
}

window.addEventListener(
'DOMContentLoaded',
() => {
NineteenEightyWooProducts.actionSelect().addEventListener(
'change',
( e ) => {
NineteenEightyWooProducts.selectMenuEvent( e );
}
);
}
);
13 changes: 2 additions & 11 deletions src/Export/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ public static function to_updated_product_body(

if ( ProductHelper::name_sync_enabled( $wc_product ) ) {
$name_props = array(
'Description' => $wc_product->get_title(),
'Description' => $wc_product->get_name(),
);

if ( $wc_product instanceof WC_Product_Variation ) {
Expand All @@ -434,16 +434,7 @@ public static function to_updated_product_body(
$product_props = array_merge( $product_props, $name_props );
}

$product_dk_currency = $wc_product->get_meta(
'1984_woo_dk_dk_currency',
true,
'edit'
);

if (
( get_woocommerce_currency() === $product_dk_currency ) &&
ProductHelper::price_sync_enabled( $wc_product )
) {
if ( ProductHelper::price_sync_enabled( $wc_product ) ) {
$price_props = array(
'CurrencyCode' => get_woocommerce_currency(),
'TaxPercent' => ProductHelper::tax_rate( $wc_product ),
Expand Down
69 changes: 69 additions & 0 deletions src/Helpers/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
use NineteenEightyFour\NineteenEightyWoo\Config;
use NineteenEightyFour\NineteenEightyWoo\Brick\Math\BigDecimal;
use NineteenEightyFour\NineteenEightyWoo\Brick\Math\RoundingMode;
use NineteenEightyFour\NineteenEightyWoo\Hooks\WooUpdateProduct as WooUpdateProductHooks;
use WC_Product;
use WC_Product_Variation;
use WC_Tax;
use WC_DateTime;
use WP_Post;

/**
* The Product Helper Class
Expand All @@ -28,6 +31,10 @@ class Product {
* @return bool True if name sync is enabled, false if not.
*/
public static function name_sync_enabled( WC_Product $wc_product ): bool {
if ( $wc_product instanceof WC_Product_Variation ) {
$wc_product = wc_get_product( $wc_product->get_parent_id() );
}

$meta_value = $wc_product->get_meta(
'1984_woo_dk_name_sync',
true,
Expand Down Expand Up @@ -55,6 +62,26 @@ public static function name_sync_enabled( WC_Product $wc_product ): bool {
* @return bool True if price sync is enabled, false if not.
*/
public static function price_sync_enabled( WC_Product $wc_product ): bool {
if ( $wc_product instanceof WC_Product_Variation ) {
$parent = wc_get_product( $wc_product->get_parent_id() );
if ( $parent ) {
$wc_product = $parent;
}
}

$product_dk_currency = $wc_product->get_meta(
'1984_woo_dk_dk_currency',
true,
'edit'
);

if (
( ! empty( $product_dk_currency ) ) &&
( get_woocommerce_currency() !== $product_dk_currency )
) {
return false;
}

$meta_value = $wc_product->get_meta(
'1984_woo_dk_price_sync',
true,
Expand Down Expand Up @@ -84,6 +111,13 @@ public static function price_sync_enabled( WC_Product $wc_product ): bool {
public static function quantity_sync_enabled(
WC_Product $wc_product
): bool {
if ( $wc_product instanceof WC_Product_Variation ) {
$parent = wc_get_product( $wc_product->get_parent_id() );
if ( $parent ) {
$wc_product = $parent;
}
}

$meta_value = $wc_product->get_meta(
'1984_woo_dk_stock_sync',
true,
Expand Down Expand Up @@ -248,4 +282,39 @@ public static function get_ledger_codes( WC_Product $wc_product ): false|object
}
return false;
}

/**
* Convert a product to variant
*
* @param int $product_id The product ID.
* @param int $parent_id The ID of the new variant's parent.
*
* @return bool True on success, false on failure.
*/
public static function convert_to_variant(
int $product_id,
int $parent_id
): bool {
if ( 'product' !== get_post_type( $product_id ) ) {
return false;
}

set_post_type( $product_id, 'product_variation' );

$wc_product = wc_get_product( $product_id );
$original_name = $wc_product->get_name();

if ( 'draft' === $wc_product->get_status( 'edit' ) ) {
$wc_product->set_status( 'private' );
}

$wc_product->set_parent_id( $parent_id );
$wc_product->set_name( $original_name );

if ( 0 !== $wc_product->save() ) {
return true;
}

return false;
}
}
114 changes: 114 additions & 0 deletions src/Hooks/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
use NineteenEightyFour\NineteenEightyWoo\Export\Product;
use NineteenEightyFour\NineteenEightyWoo\Export\SalesPerson;
use NineteenEightyFour\NineteenEightyWoo\Export\Customer;
use NineteenEightyFour\NineteenEightyWoo\Helpers\Product as ProductHelper;
use stdClass;
use WP_Screen;

/**
* The NineteenEightyWoo Admin class
Expand Down Expand Up @@ -40,6 +42,118 @@ public function __construct() {
array( __CLASS__, 'enqueue_styles_and_scripts' )
);
}

add_action(
'current_screen',
array( __CLASS__, 'enqueue_products_styles_and_scripts' ),
10
);

add_filter(
'bulk_actions-edit-product',
array( __CLASS__, 'register_product_to_variant_bulk_action' ),
10
);

add_filter(
'handle_bulk_actions-edit-product',
array( __CLASS__, 'handle_product_to_variant_bulk_action' ),
10,
3
);
}

/**
* Enqueue the styles and scripts for the products screen
*
* @param WP_Screen $current_screen The current screen. In our case it
* should be the `edit-product` screen.
*/
public static function enqueue_products_styles_and_scripts( WP_Screen $current_screen ): void {
if ( 'edit-product' === $current_screen->id ) {
wp_enqueue_style(
handle: 'nineteen-eighty-woo-products',
src: plugins_url( 'style/products.css', dirname( __DIR__ ) ),
ver: self::ASSET_VERSION
);

wp_enqueue_script(
'nineteen-eighty-woo',
plugins_url( 'js/products.js', dirname( __DIR__ ) ),
array( 'wp-api', 'wp-data' ),
self::ASSET_VERSION,
false,
);
}
}

/**
* Register the product-to-variant bulk action
*
* This enables a bulk action that changes products into variants of
* another. This is useful when fetching products from DK as there is no
* orhodox way for managing variant products in DK.
*
* @param array $bulk_actions The current bulk actions.
*
* @return array The modified array, with `convert_to_variant` added to it.
*/
public static function register_product_to_variant_bulk_action(
array $bulk_actions
): array {
$bulk_actions['convert_to_variant'] = __(
'Convert to Product Variant',
'1984-dk-woo'
);

return $bulk_actions;
}

/**
* The handler for the product-to-variant bulk action
*
* @param string $sendback The original redirect URL.
* @param string $doaction The name of the action; in our case `convert_to_variant`.
* @param array $post_ids An array containing the IDs for the posts/products selected.
*
* @return string The URL to redirect to.
*/
public static function handle_product_to_variant_bulk_action(
string $sendback,
string $doaction,
array $post_ids
): string {
if ( 'convert_to_variant' !== $doaction ) {
return $sendback;
}

// Nonce check is handled by the WP Core.
// phpcs:ignore WordPress.Security.NonceVerification
if ( ! isset( $_GET['action_post_id'] ) ) {
return $sendback;
}

$parent_id = intval(
sanitize_text_field(
// Nonce check is handled by the WP Core.
// phpcs:ignore WordPress.Security.NonceVerification
wp_unslash( $_GET['action_post_id'] )
)
);

if ( false === wc_get_product( $parent_id ) ) {
return $sendback;
}

foreach ( $post_ids as $p ) {
ProductHelper::convert_to_variant( $p, $parent_id );
}

return add_query_arg(
'bulk_emailed_posts',
count( $post_ids ),
$sendback
);
}

/**
Expand Down
22 changes: 19 additions & 3 deletions src/Hooks/WooUpdateProduct.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,13 @@ public static function before_post_delete( int $post_id ): void {
return;
}

if ( 'product' === get_post_type( $post_id ) ) {
if (
in_array(
get_post_type( $post_id ),
array( 'product', 'product_variation' ),
true
)
) {
$wc_product = wc_get_product( $post_id );

if ( ! ProductHelper::should_sync( $wc_product ) ) {
Expand Down Expand Up @@ -126,11 +132,18 @@ public static function post_status_change(
return;
}

if ( 'product' !== get_post_type( $post ) ) {
if (
false ===
in_array(
get_post_type( $post ),
array( 'product', 'product_variation' ),
true
)
) {
return;
}

$wc_product = wc_get_product( $post );
$wc_product = wc_get_product( $post->ID );

if ( ! ProductHelper::should_sync( $wc_product ) ) {
return;
Expand All @@ -140,6 +153,9 @@ public static function post_status_change(
case 'draft':
ExportProduct::hide_from_webshop_in_dk( $wc_product );
break;
case 'private':
ExportProduct::hide_from_webshop_in_dk( $wc_product );
break;
case 'publish':
ExportProduct::show_in_webshop_in_dk( $wc_product );
}
Expand Down
7 changes: 6 additions & 1 deletion src/Import/Products.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use WC_Product;
use WP_Error;
use WC_Tax;
use WC_Product_Variation;

/**
* The Products import class
Expand Down Expand Up @@ -329,7 +330,11 @@ public static function update_product_from_json(
if ( true === $json_object->ShowItemInWebShop ) {
$wc_product->set_status( 'Publish' );
} else {
$wc_product->set_status( 'Draft' );
if ( $wc_product instanceof WC_Product_Variation ) {
$wc_product->set_status( 'Private' );
} else {
$wc_product->set_status( 'Draft' );
}
}

if (
Expand Down
3 changes: 3 additions & 0 deletions style/products.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
input#action_post_id_input {
width: 7em;
}
2 changes: 1 addition & 1 deletion views/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class="regular-text api-key-input"
<?php esc_html_e( 'Sync Product Names with DK', '1984-dk-woo' ); ?>
</label>
<p class="description">
<?php esc_html_e( 'If enabled, product names are synced between DK and WooCommerce. Disable this if you would like to be able to use separate product names in your WooCommerce shop from the ones in DK.', '1984-dk-woo' ); ?>
<?php esc_html_e( 'If enabled, product names are synced between DK and WooCommerce. Disable this if you would like to be able to use separate product names in your WooCommerce shop from the ones in DK or simply prevent WooCommerce from affecting product descriptions in DK.', '1984-dk-woo' ); ?>
</p>
</td>
</tr>
Expand Down

0 comments on commit a98da51

Please sign in to comment.