Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Index posts after Woocommerce custom sort #2965

Merged
merged 9 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions includes/classes/Feature/WooCommerce/WooCommerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,10 @@ public function setup() {
add_filter( 'ep_weighting_default_post_type_weights', [ $this, 'add_product_default_post_type_weights' ], 10, 2 );
add_filter( 'ep_prepare_meta_data', [ $this, 'add_variations_skus_meta' ], 10, 2 );
add_filter( 'request', [ $this, 'admin_product_list_request_query' ], 9 );

// Custom product ordering
add_action( 'ep_admin_notices', [ $this, 'maybe_display_notice_about_product_ordering' ] );
add_action( 'woocommerce_after_product_ordering', [ $this, 'action_sync_on_woocommerce_sort_single' ], 10, 2 );
}

/**
Expand Down Expand Up @@ -1169,4 +1173,60 @@ protected function should_integrate_with_query( $query ) {

return true;
}

/**
* Depending on the number of products display an admin notice in the custom sort screen for WooCommerce Products
*
* @since 4.4.0
* @param array $notices Current ElasticPress admin notices
* @return array
*/
public function maybe_display_notice_about_product_ordering( $notices ) {
global $pagenow, $wp_query;

/**
* Make sure we're on edit.php in admin dashboard.
*/
if ( ! is_admin() || 'edit.php' !== $pagenow || empty( $wp_query->query['orderby'] ) || 'menu_order title' !== $wp_query->query['orderby'] ) {
return $notices;
}

/* This filter is documented in /includes/classes/IndexHelper.php */
$documents_per_page_sync = (int) apply_filters( 'ep_index_default_per_page', Utils\get_option( 'ep_bulk_setting', 350 ) );
if ( $documents_per_page_sync >= $wp_query->found_posts ) {
return $notices;
}

$notices['woocommerce_custom_sort'] = [
'html' => sprintf(
/* translators: Sync Page URL */
__( 'Due to the number of products in the site, you will need to <a href="%s">resync</a> after applying a custom sort order.', 'elasticpress' ),
Utils\get_sync_url()
),
'type' => 'warning',
'dismiss' => true,
];

return $notices;
}

/**
* Conditionally resync products after applying a custom order.
*
* @since 4.4.0
* @param int $sorting_id ID of post dragged and dropped
* @param array $menu_orders Post IDs and their new menu_order value
*/
public function action_sync_on_woocommerce_sort_single( $sorting_id, $menu_orders ) {
/* This filter is documented in /includes/classes/IndexHelper.php */
$documents_per_page_sync = (int) apply_filters( 'ep_index_default_per_page', Utils\get_option( 'ep_bulk_setting', 350 ) );
if ( $documents_per_page_sync < count( $menu_orders ) ) {
return;
}

$sync_manager = Indexables::factory()->get( 'post' )->sync_manager;
foreach ( $menu_orders as $post_id => $order ) {
$sync_manager->add_to_queue( $post_id );
}
}
}
2 changes: 1 addition & 1 deletion includes/classes/SyncManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public function index_sync_queue() {
}

// Bulk sync them all.
Indexables::factory()->get( $this->indexable_slug )->bulk_index( array_keys( $this->sync_queue ) );
Indexables::factory()->get( $this->indexable_slug )->bulk_index_dynamically( array_keys( $this->sync_queue ) );

/**
* Make sure to reset sync queue in case an shutdown happens before a redirect
Expand Down
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"license": "GPL-2.0-or-later",
"description": "A fast and flexible search and query engine for WordPress.",
"devDependencies": {
"@4tw/cypress-drag-drop": "^2.2.1",
"@wordpress/env": "^5.0.0",
"10up-toolkit": "^3.0.0",
"classnames": "^2.3.1",
Expand Down
59 changes: 58 additions & 1 deletion tests/cypress/integration/features/woocommerce.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ describe('WooCommerce Feature', () => {
cy.login();
cy.maybeEnableFeature('protected_content');
cy.maybeEnableFeature('woocommerce');
cy.activatePlugin('woocommerce');
cy.activatePlugin('woocommerce', 'wpCli');
});

it('Can fetch orders and products from Elasticsearch', () => {
Expand Down Expand Up @@ -237,5 +237,62 @@ describe('WooCommerce Feature', () => {
`${userData.firstName} ${userData.lastName}`,
);
});

it('Can show the correct order of products after custom sort order', () => {
// Content Items per Index Cycle is greater than number of products
cy.setPerIndexCycle();
cy.visitAdminPage('edit.php?post_type=product&orderby=menu_order+title&order=ASC');
cy.get('div[data-ep-notice="woocommerce_custom_sort"]').should('not.exist');

let thirdProductId = '';
cy.get('#the-list tr:eq(2)')
.as('thirdProduct')
.invoke('attr', 'id')
.then((id) => {
thirdProductId = id;
});

cy.get('@thirdProduct')
.drag('#the-list tr:eq(0)', { force: true })
.then(() => {
cy.get('#the-list tr:eq(0)').should('have.id', thirdProductId);

cy.refreshIndex('post').then(() => {
cy.reload();
cy.get(
'#debug-menu-target-EP_Debug_Bar_ElasticPress .ep-query-debug',
).should('contain.text', 'Query Response Code: HTTP 200');
cy.get('#the-list tr:eq(0)').should('have.id', thirdProductId);
});
});

// Content Items per Index Cycle is lower than number of products
cy.setPerIndexCycle(20);
cy.visitAdminPage('edit.php?post_type=product&orderby=menu_order+title&order=ASC');
cy.get('div[data-ep-notice="woocommerce_custom_sort"]').should('exist');

cy.get('#the-list tr:eq(2)')
.as('thirdProduct')
.invoke('attr', 'id')
.then((id) => {
thirdProductId = id;
});

cy.get('@thirdProduct')
.drag('#the-list tr:eq(0)', { force: true })
.then(() => {
cy.get('#the-list tr:eq(0)').should('have.id', thirdProductId);

cy.refreshIndex('post').then(() => {
cy.reload();
cy.get(
'#debug-menu-target-EP_Debug_Bar_ElasticPress .ep-query-debug',
).should('contain.text', 'Query Response Code: HTTP 200');
cy.get('#the-list tr:eq(0)').should('have.not.id', thirdProductId);
});
});

cy.setPerIndexCycle();
});
});
});
1 change: 1 addition & 0 deletions tests/cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import 'cypress-file-upload';
import './commands/block-editor';
import '@4tw/cypress-drag-drop';

Cypress.Commands.add('login', (username = 'admin', password = 'password') => {
cy.visit(`/wp-admin`);
Expand Down