Skip to content

Commit 400529e

Browse files
authored
Merge pull request #758 from 10up/feature/update-embedding-model
Updates to the OpenAI Embeddings Provider
2 parents 02c60a3 + b4e85bd commit 400529e

File tree

7 files changed

+658
-239
lines changed

7 files changed

+658
-239
lines changed

includes/Classifai/Admin/Notifications.php

+168-90
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Classifai\Admin;
44

55
use Classifai\Features\DescriptiveTextGenerator;
6+
use Classifai\Features\Classification;
67

78
class Notifications {
89

@@ -24,21 +25,33 @@ public function can_register(): bool {
2425
* Register the actions needed.
2526
*/
2627
public function register() {
27-
add_action( 'classifai_activation_hook', [ $this, 'add_activation_notice' ] );
2828
add_action( 'admin_notices', [ $this, 'maybe_render_notices' ], 0 );
29-
add_action( 'admin_notices', [ $this, 'thresholds_update_notice' ] );
30-
add_action( 'admin_notices', [ $this, 'v3_migration_completed_notice' ] );
3129
add_action( 'admin_enqueue_scripts', [ $this, 'add_dismiss_script' ] );
3230
add_action( 'wp_ajax_classifai_dismiss_notice', [ $this, 'ajax_maybe_dismiss_notice' ] );
3331
}
3432

3533
/**
36-
* Respond to the activation hook.
34+
* Render any needed admin notices.
3735
*/
3836
public function maybe_render_notices() {
37+
// Only show these notices to admins.
38+
if ( ! current_user_can( 'manage_options' ) ) {
39+
return;
40+
}
41+
42+
$this->render_registration_notice();
43+
$this->render_activation_notice();
44+
$this->thresholds_update_notice();
45+
$this->v3_migration_completed_notice();
46+
$this->render_embeddings_notice();
47+
}
48+
49+
/**
50+
* Render a registration notice, if needed.
51+
*/
52+
public function render_registration_notice() {
3953
$registration_settings = get_option( 'classifai_settings' );
40-
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
41-
$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
54+
$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
4255

4356
if (
4457
'classifai' === $page &&
@@ -53,103 +66,44 @@ public function maybe_render_notices() {
5366
</div>
5467
<?php
5568
}
56-
57-
$needs_setup = get_transient( 'classifai_activation_notice' );
58-
if ( $needs_setup ) {
59-
$onboarding = new Onboarding();
60-
if ( $onboarding->is_onboarding_completed() ) {
61-
delete_transient( 'classifai_activation_notice' );
62-
return;
63-
}
64-
65-
// Prevent showing the default WordPress "Plugin Activated" notice.
66-
unset( $_GET['activate'] ); // phpcs:ignore WordPress.Security.NonceVerification
67-
?>
68-
<div data-notice="plugin-activation" class="notice notice-success is-dismissible">
69-
<div id="classifai-activation-notice">
70-
<div class="classifai-logo">
71-
<img src="<?php echo esc_url( CLASSIFAI_PLUGIN_URL . 'assets/img/classifai.png' ); ?>" alt="<?php esc_attr_e( 'ClassifAI', 'classifai' ); ?>" />
72-
</div>
73-
<h3 class="classifai-activation-message">
74-
<?php esc_html_e( 'Congratulations, the ClassifAI plugin is now activated.', 'classifai' ); ?>
75-
</h3>
76-
<a class="classifai-button" href="<?php echo esc_url( admin_url( 'admin.php?page=classifai_setup' ) ); ?>">
77-
<?php esc_html_e( 'Start setup', 'classifai' ); ?>
78-
</a>
79-
</div>
80-
</div>
81-
<?php
82-
delete_transient( 'classifai_activation_notice' );
83-
}
8469
}
8570

8671
/**
87-
* Print out a script to dismiss a notice.
88-
*
89-
* This allows us to save that a user has dismissed a notice.
90-
*
91-
* Influenced by https://github.com/WPTT/admin-notices/blob/af52f563398b42cff82d38eefa55c8121d698ebe/src/Dismiss.php#L77
72+
* Render an activation notice, if needed.
9273
*/
93-
public function add_dismiss_script() {
94-
$nonce = wp_create_nonce( 'classifai_dismissible_notice' );
95-
$admin_ajax_url = esc_url( admin_url( 'admin-ajax.php' ) );
96-
97-
$script = <<<EOD
98-
jQuery( function() {
99-
const dismissBtns = document.querySelectorAll( '.classifai-dismissible-notice' );
100-
101-
if ( ! dismissBtns.length ) {
102-
return;
103-
}
104-
105-
// Add an event listener to the dismiss buttons.
106-
dismissBtns.forEach( function( dismissBtn ) {
107-
dismissBtn.addEventListener( 'click', function( event ) {
108-
const id = dismissBtn.getAttribute( 'data-notice' );
109-
110-
if ( ! id ) {
111-
return;
112-
}
113-
114-
const httpRequest = new XMLHttpRequest();
115-
let postData = '';
116-
117-
// Build the data to send in our request.
118-
// Data has to be formatted as a string here.
119-
postData += 'notice_id=' + id;
120-
postData += '&action=classifai_dismiss_notice';
121-
postData += '&nonce=$nonce';
122-
123-
httpRequest.open( 'POST', '$admin_ajax_url' );
124-
httpRequest.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' )
125-
httpRequest.send( postData );
126-
});
127-
});
128-
});
129-
EOD;
130-
131-
wp_add_inline_script( 'common', $script, 'after' );
132-
}
74+
public function render_activation_notice() {
75+
$needs_setup = get_transient( 'classifai_activation_notice' );
13376

134-
/**
135-
* Verify ajax request and dismiss the notice.
136-
*
137-
* Influenced by https://github.com/WPTT/admin-notices/blob/af52f563398b42cff82d38eefa55c8121d698ebe/src/Dismiss.php#L133
138-
*/
139-
public function ajax_maybe_dismiss_notice() {
140-
if ( ! isset( $_POST['action'] ) || 'classifai_dismiss_notice' !== $_POST['action'] ) {
77+
if ( ! $needs_setup ) {
14178
return;
14279
}
14380

144-
if ( ! isset( $_POST['notice_id'] ) ) {
81+
$onboarding = new Onboarding();
82+
if ( $onboarding->is_onboarding_completed() ) {
83+
delete_transient( 'classifai_activation_notice' );
14584
return;
14685
}
14786

148-
check_ajax_referer( 'classifai_dismissible_notice', 'nonce' );
87+
// Prevent showing the default WordPress "Plugin Activated" notice.
88+
unset( $_GET['activate'] ); // phpcs:ignore WordPress.Security.NonceVerification
89+
?>
14990

150-
$notice_id = sanitize_text_field( wp_unslash( $_POST['notice_id'] ) );
91+
<div data-notice="plugin-activation" class="notice notice-success is-dismissible">
92+
<div id="classifai-activation-notice">
93+
<div class="classifai-logo">
94+
<img src="<?php echo esc_url( CLASSIFAI_PLUGIN_URL . 'assets/img/classifai.png' ); ?>" alt="<?php esc_attr_e( 'ClassifAI', 'classifai' ); ?>" />
95+
</div>
96+
<h3 class="classifai-activation-message">
97+
<?php esc_html_e( 'Congratulations, the ClassifAI plugin is now activated.', 'classifai' ); ?>
98+
</h3>
99+
<a class="classifai-button" href="<?php echo esc_url( admin_url( 'admin.php?page=classifai_setup' ) ); ?>">
100+
<?php esc_html_e( 'Start setup', 'classifai' ); ?>
101+
</a>
102+
</div>
103+
</div>
151104

152-
update_user_meta( get_current_user_id(), "classifai_dismissed_{$notice_id}", true );
105+
<?php
106+
delete_transient( 'classifai_activation_notice' );
153107
}
154108

155109
/**
@@ -235,6 +189,7 @@ public function v3_migration_completed_notice() {
235189
return;
236190
}
237191
?>
192+
238193
<div class="notice notice-info is-dismissible classifai-dismissible-notice classifai-migation-notice" data-notice="<?php echo esc_attr( $key ); ?>">
239194
<p>
240195
<?php
@@ -251,6 +206,129 @@ public function v3_migration_completed_notice() {
251206
?>
252207
</p>
253208
</div>
209+
210+
<?php
211+
}
212+
213+
/**
214+
* Render a notice about needing to regenerate embeddings.
215+
*/
216+
public function render_embeddings_notice() {
217+
// Bail if no need to show the notice.
218+
if ( get_option( 'classifai_hide_embeddings_notice', false ) ) {
219+
return;
220+
}
221+
222+
// Ensure the feature exists.
223+
if ( ! class_exists( 'Classifai\Features\Classification' ) ) {
224+
return;
225+
}
226+
227+
$feature_instance = new Classification();
228+
229+
// Don't show the notice if the feature is not enabled.
230+
if ( ! $feature_instance->is_feature_enabled() ) {
231+
return;
232+
}
233+
234+
// Don't show the notice if the provider is not OpenAI Embeddings.
235+
$provider = $feature_instance->get_settings( 'provider' );
236+
if ( 'openai_embeddings' !== $provider ) {
237+
return;
238+
}
239+
240+
$key = 'embedding_regen_completed';
241+
242+
// Don't show the notice if the user has already dismissed it.
243+
if ( get_user_meta( get_current_user_id(), "classifai_dismissed_{$key}", true ) ) {
244+
return;
245+
}
246+
?>
247+
248+
<div class="notice notice-warning is-dismissible classifai-dismissible-notice" data-notice="<?php echo esc_attr( $key ); ?>">
249+
<p>
250+
<?php
251+
echo wp_kses_post(
252+
sprintf(
253+
// translators: %1$s: Feature specific message; %2$s: URL to Feature settings.
254+
__( 'ClassifAI has updated to the <code>text-embedding-3-small</code> embeddings model. <br>This requires regenerating any stored embeddings for functionality to work properly. <br><a href="%1$s">Click here to do that</a>, noting this will make multiple API requests to OpenAI.', 'classifai' ),
255+
wp_nonce_url( admin_url( 'tools.php?page=classifai&tab=language_processing&feature=feature_classification' ), 'regen_embeddings', 'embeddings_nonce' )
256+
)
257+
);
258+
?>
259+
</p>
260+
</div>
261+
254262
<?php
255263
}
264+
265+
/**
266+
* Print out a script to dismiss a notice.
267+
*
268+
* This allows us to save that a user has dismissed a notice.
269+
*
270+
* Influenced by https://github.com/WPTT/admin-notices/blob/af52f563398b42cff82d38eefa55c8121d698ebe/src/Dismiss.php#L77
271+
*/
272+
public function add_dismiss_script() {
273+
$nonce = wp_create_nonce( 'classifai_dismissible_notice' );
274+
$admin_ajax_url = esc_url( admin_url( 'admin-ajax.php' ) );
275+
276+
$script = <<<EOD
277+
jQuery( function() {
278+
const dismissNotices = document.querySelectorAll( '.classifai-dismissible-notice' );
279+
280+
if ( ! dismissNotices.length ) {
281+
return;
282+
}
283+
284+
// Add an event listener to the dismiss buttons.
285+
dismissNotices.forEach( function( dismissNotice ) {
286+
let dismissBtn = dismissNotice.querySelector( '.notice-dismiss' );
287+
dismissBtn.addEventListener( 'click', function( event ) {
288+
const id = dismissNotice.getAttribute( 'data-notice' );
289+
290+
if ( ! id ) {
291+
return;
292+
}
293+
294+
const httpRequest = new XMLHttpRequest();
295+
let postData = '';
296+
297+
// Build the data to send in our request.
298+
// Data has to be formatted as a string here.
299+
postData += 'notice_id=' + id;
300+
postData += '&action=classifai_dismiss_notice';
301+
postData += '&nonce=$nonce';
302+
303+
httpRequest.open( 'POST', '$admin_ajax_url' );
304+
httpRequest.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' )
305+
httpRequest.send( postData );
306+
});
307+
});
308+
});
309+
EOD;
310+
311+
wp_add_inline_script( 'common', $script, 'after' );
312+
}
313+
314+
/**
315+
* Verify ajax request and dismiss the notice.
316+
*
317+
* Influenced by https://github.com/WPTT/admin-notices/blob/af52f563398b42cff82d38eefa55c8121d698ebe/src/Dismiss.php#L133
318+
*/
319+
public function ajax_maybe_dismiss_notice() {
320+
if ( ! isset( $_POST['action'] ) || 'classifai_dismiss_notice' !== $_POST['action'] ) {
321+
return;
322+
}
323+
324+
if ( ! isset( $_POST['notice_id'] ) ) {
325+
return;
326+
}
327+
328+
check_ajax_referer( 'classifai_dismissible_notice', 'nonce' );
329+
330+
$notice_id = sanitize_text_field( wp_unslash( $_POST['notice_id'] ) );
331+
332+
update_user_meta( get_current_user_id(), "classifai_dismissed_{$notice_id}", true );
333+
}
256334
}

includes/Classifai/Command/ClassifaiCommand.php

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use Classifai\Providers\Watson\APIRequest;
1212
use Classifai\Providers\Watson\Classifier;
1313
use Classifai\Normalizer;
14-
use Classifai\Providers\Watson\PostClassifier;
1514
use Classifai\Providers\OpenAI\Embeddings;
1615

1716
use function Classifai\Providers\Watson\get_username;

includes/Classifai/Helpers.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use Classifai\Features\Classification;
66
use Classifai\Providers\Provider;
77
use Classifai\Admin\UserProfile;
8-
use Classifai\Providers\Watson\NLU;
98
use Classifai\Providers\OpenAI\Embeddings;
109
use Classifai\Services\Service;
1110
use Classifai\Services\ServicesManager;
@@ -589,7 +588,7 @@ function get_classification_feature_enabled( string $classify_by ): bool {
589588
$settings = ( new Classification() )->get_settings();
590589

591590
return filter_var(
592-
$settings[ $classify_by ],
591+
isset( $settings[ $classify_by ] ) ?? false,
593592
FILTER_VALIDATE_BOOLEAN
594593
);
595594
}

includes/Classifai/Normalizer.php

-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ public function normalize_content( $post_content, $post_title = '', $post_id = f
4646
/* Strip HTML entities */
4747
$post_content = preg_replace( '/&#?[a-z0-9]{2,8};/i', '', $post_content );
4848

49-
/* Strip abbreviations */
50-
$post_content = preg_replace( '/[A-Z][A-Z]+/', '', $post_content );
51-
5249
/* Replace HTML linebreaks with newlines */
5350
$post_content = preg_replace( '#<br\s?/?>#', "\n\n", $post_content );
5451

0 commit comments

Comments
 (0)