Skip to content

Commit

Permalink
Fix: ElasticPress v5.0.0 API changes.
Browse files Browse the repository at this point in the history
Ref: wpmlbridge-288
  • Loading branch information
decodekult committed Nov 5, 2023
1 parent a00e02c commit c702222
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 74 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ tests/wordpress
Thumbs.db
/tests/compatibility/*.txt
.DS_Store
.vscode

inc/sandbox.inc
*.sh
Expand Down
39 changes: 29 additions & 10 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ class Plugin {
// ElasticPrtess loads its features at plugins_loaded:10.
const INIT_PRIORITY = 11;

// Before ElasticPress 5.0.0, the Dashboard sync was run over AJAX.
// After ElasticPress 5.0.0, the Dashboard sync is run over the REST API.
const DASHBOARD_SYNC_API_CHANGE_V1 = '5.0.0';

public static function init() {
add_action( 'plugins_loaded', function () {
if ( ! defined( 'EP_VERSION' ) || version_compare( EP_VERSION, '3.0.0', '<' ) ) {
Expand All @@ -18,6 +22,8 @@ public static function init() {
return;
}

$elasticPressVersion = EP_VERSION;

$activeLanguagesData = apply_filters( 'wpml_active_languages', [] );
$activeLanguages = array_keys( $activeLanguagesData );
$defaultLanguage = apply_filters( 'wpml_default_language', '' );
Expand All @@ -37,6 +43,26 @@ public static function init() {
);
$indicesManager->addHooks();

$syncDashboard = version_compare( $elasticPressVersion, self::DASHBOARD_SYNC_API_CHANGE_V1, '<' )
? new Sync\DashboardAjax(
$indexables,
$indicesManager,
new Manager\DashboardStatus(
$activeLanguages
),
$activeLanguages,
$defaultLanguage
)
: new Sync\DashboardRest(
$indexables,
$indicesManager,
new Manager\DashboardStatus(
$activeLanguages
),
$activeLanguages,
$defaultLanguage
);

$feature = new Feature(
new Field\Search(
$elasticsearchVersion,
Expand All @@ -50,20 +76,13 @@ public static function init() {
$defaultLanguage,
$currentLanguage
),
new Sync\Dashboard(
$indexables,
$indicesManager,
new Manager\DashboardStatus(
$activeLanguages
),
$activeLanguages,
$defaultLanguage
),
$syncDashboard,
new Sync\Singular(
$indexables,
$indicesManager,
$activeLanguages,
$defaultLanguage
$defaultLanguage,
$elasticPressVersion
),
new Sync\CLI(
$indexables,
Expand Down
105 changes: 47 additions & 58 deletions src/Sync/Dashboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,31 @@

use WPML\ElasticPress\Traits\ManageIndexables;

class Dashboard {
abstract class Dashboard {

use ManageIndexables;

/** @var Indexables */
private $indexables;

/** @var Indices */
private $indicesManager;
protected $indicesManager;

/** @var DashboardStatus */
private $status;
protected $status;

/** @var array */
private $activeLanguages;
protected $activeLanguages;

/** @var string */
private $defaultLanguage;

/** @var string */
private $currentLanguage = '';

/** @var array */
private $fullIndexArgs = [];

/**
* @param Indexables $indexables
* @param Indices $indicesManager
Expand All @@ -54,20 +57,30 @@ public function __construct(
$this->defaultLanguage = $defaultLanguage;
}

public function addHooks() {
if ( 0 === count( $this->activeLanguages ) ) {
abstract public function addHooks();

/**
* @param array $args
*/
protected function setFullIndexArgs( $args ) {
$this->fullIndexArgs = $args;
}

protected function setUpAndRun() {
$this->prepare();
if ( empty( $this->status->get('currentLanguage') ) ) {
return;
}
$this->maybePutMapping();
$this->beforeFullIndex();

add_action( 'wp_ajax_ep_index', [ $this, 'action_wp_ajax_ep_index' ], 9 );
add_action( 'wp_ajax_ep_cancel_index', [ $this, 'action_wp_ajax_ep_cancel_index' ], 9 );
}
// This happens on an AJAX call, hence on admin: force the display-as-translated snippet in queries
add_filter( 'wpml_should_use_display_as_translated_snippet', '__return_true' );

private function setUp() {
$this->status->prepare();
$this->runFullIndex( $this->fullIndexArgs );
}

private function tearDown() {
protected function tearDown() {
$this->indicesManager->clearCurrentIndexLanguage();
$this->status->delete();
}
Expand All @@ -82,25 +95,14 @@ private function clearCurrentLanguage() {
$this->indicesManager->clearCurrentIndexLanguage();
}

private function isDashboardSync() {
if ( ! check_ajax_referer( 'ep_dashboard_nonce', 'nonce', false ) || ! EP_DASHBOARD_SYNC ) {
wp_send_json_error( null, 403 );
exit;
}

$index_meta = Utils\get_indexing_status();

if ( isset( $index_meta['method'] ) && 'cli' === $index_meta['method'] ) {
return false;
}

return true;
private function prepare() {
$this->status->prepare();
}

private function maybePutMapping() {
$putMapping = ! empty( $_REQUEST['put_mapping'] );

if ( $putMapping && false === $this->status->get('putMapping') ) {
if ( ( $putMapping || $forcePutMapping ) && false === $this->status->get('putMapping') ) {
$this->indicesManager->clearAllIndices();
$this->status->set('putMapping', true);
}
Expand All @@ -116,44 +118,31 @@ private function beforeFullIndex() {
$this->status->logIndexablesToReset( $this->deactivateIndexables() );
}

public function action_wp_ajax_ep_cancel_index() {
if ( false === $this->isDashboardSync() ) {
return;
}
$this->tearDown();
}

public function action_wp_ajax_ep_index() {
if ( false === $this->isDashboardSync() ) {
return;
}
$this->setUp();
if ( empty( $this->status->get('currentLanguage') ) ) {
return;
}
$this->maybePutMapping();
$this->beforeFullIndex();

// This happens on an AJAX call, hence on admin: force the display-as-translated snippet in queries
add_filter( 'wpml_should_use_display_as_translated_snippet', '__return_true' );

IndexHelper::factory()->full_index(
/**
* @param array $forcedArgs
*/
private function runFullIndex( $forcedArgs = [] ) {
$args = array_merge(
[
'method' => 'dashboard',
'put_mapping' => false,
'output_method' => [ $this, 'indexOutput' ],
'show_errors' => true,
'network_wide' => 0,
]
'show_errors' => true,
],
$forcedArgs
);

$args['put_mapping'] = false;
$args['output_method'] = [ $this, 'indexOutput' ];

IndexHelper::factory()->full_index( $args );
}

private function syncComplete() {
$message = [
'message' => 'Sync complete',
'message' => 'Sync complete',
'index_meta' => null,
'totals' => $this->status->get('totals'),
'status' => 'success'
'totals' => $this->status->get('totals'),
'status' => 'success'
];
$this->tearDown();
wp_send_json_success( $message );
Expand Down Expand Up @@ -200,9 +189,9 @@ private function setLanguageCompletedResponse( $message ) {
// Hijack the message data so the next language gets processed
$message['totals'] = [];
$message['index_meta'] = [
'method' => 'web',
'totals' => $this->status->get('totals'),
'sync_stack' => [],
'method' => 'web',
'totals' => $this->status->get('totals'),
'sync_stack' => [],
'put_mapping' => $this->status->get('putMapping'),
];
return $message;
Expand Down
59 changes: 59 additions & 0 deletions src/Sync/DashboardAjax.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace WPML\ElasticPress\Sync;

use ElasticPress\Indexables;
use ElasticPress\IndexHelper;
use ElasticPress\Utils;

use WPML\ElasticPress\Manager\Indices;
use WPML\ElasticPress\Manager\DashboardStatus;

use WPML\ElasticPress\Sync\Dashboard;

use WPML\ElasticPress\Traits\ManageIndexables;

/**
* Before ElasticPress 5.0.0 the Dashboard sync was run over AJAX.
*/
class DashboardAjax extends Dashboard {

public function addHooks() {
if ( 0 === count( $this->activeLanguages ) ) {
return;
}

add_action( 'wp_ajax_ep_index', [ $this, 'action_wp_ajax_ep_index' ], 9 );
add_action( 'wp_ajax_ep_cancel_index', [ $this, 'action_wp_ajax_ep_cancel_index' ], 9 );
}

private function isDashboardSync() {
if ( ! check_ajax_referer( 'ep_dashboard_nonce', 'nonce', false ) || ! EP_DASHBOARD_SYNC ) {
wp_send_json_error( null, 403 );
exit;
}

$index_meta = Utils\get_indexing_status();

if ( isset( $index_meta['method'] ) && 'cli' === $index_meta['method'] ) {
return false;
}

return true;
}

public function action_wp_ajax_ep_index() {
if ( false === $this->isDashboardSync() ) {
return;
}
$this->setUpAndRun();
}

public function action_wp_ajax_ep_cancel_index() {
if ( false === $this->isDashboardSync() ) {
return;
}
$this->tearDown();
}

}
69 changes: 69 additions & 0 deletions src/Sync/DashboardRest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace WPML\ElasticPress\Sync;

use ElasticPress\Indexables;
use ElasticPress\IndexHelper;
use ElasticPress\Utils;

use WPML\ElasticPress\Manager\Indices;
use WPML\ElasticPress\Manager\DashboardStatus;

use WPML\ElasticPress\Sync\Dashboard;

use WPML\ElasticPress\Traits\ManageIndexables;

/**
* After ElasticPress 5.0.0 the Dashboard sync was run over the REST API.
*/
class DashboardRest extends Dashboard {

public function addHooks() {
if ( 0 === count( $this->activeLanguages ) ) {
return;
}

add_filter( 'rest_request_before_callbacks', [ $this, 'rest_request_before_callbacks' ], 10, 3 ) ;
}

private function isSyncMethod( $method, $request ) {
if ( $method !== $request->get_method() ) {
return false;
}

$route = $request->get_route();
if ( preg_match( "/^\/elasticpress\/v\d+\/sync$/", $route ) ) {
return true;
}

return false;
}

/**
* @param \WP_REST_Response|\WP_HTTP_Response|\WP_Error|mixed $response
* @param array $handler
* @param \WP_REST_Request $request
*
* @return \WP_REST_Response|\WP_HTTP_Response|\WP_Error|mixed
*/
public function rest_request_before_callbacks( $response, $handler, $request ) {
$capability = Utils\get_capability();

if ( ! current_user_can( $capability ) ) {
return $response;
}

if ( $this->isSyncMethod( 'POST', $request ) ) {
$this->setFullIndexArgs( $request->get_params() );
$this->setUpAndRun();
}

if ( $this->isSyncMethod( 'DELETE', $request ) ) {
$this->tearDown();
}

return $response;

}

}
Loading

0 comments on commit c702222

Please sign in to comment.