From b6a9fb2ea32a47591b2c5833ba318ea4563bad1a Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Thu, 11 May 2023 14:47:40 -0600 Subject: [PATCH 1/6] Add new helper function to find the provider class a service belongs to. Use this anywhere we need this information, instead of using the first provider class, which may not always be what we want. --- includes/Classifai/Helpers.php | 24 ++++++++++ .../Classifai/Services/ImageProcessing.php | 46 ++++++++----------- .../Classifai/Services/LanguageProcessing.php | 14 ++---- includes/Classifai/Services/Personalizer.php | 21 +++++---- includes/Classifai/Services/Service.php | 8 +++- 5 files changed, 66 insertions(+), 47 deletions(-) diff --git a/includes/Classifai/Helpers.php b/includes/Classifai/Helpers.php index 0d605675c..87a157ef9 100644 --- a/includes/Classifai/Helpers.php +++ b/includes/Classifai/Helpers.php @@ -5,6 +5,7 @@ use Classifai\Providers\Provider; use Classifai\Services\Service; use Classifai\Services\ServicesManager; +use WP_Error; /** * Miscellaneous Helper functions to access different parts of the @@ -661,3 +662,26 @@ function clean_input( string $key = '', bool $is_get = false, string $sanitize_c return false; } + +/** + * Find the provider class that a service belongs to. + * + * @param array $provider_classes Provider classes to look in. + * @param string $service_name Service name to look for. + * @return Provider|WP_Error + */ +function find_provider_class( array $provider_classes = [], string $service_name = '' ) { + $provider = ''; + + foreach ( $provider_classes as $provider_class ) { + if ( $service_name === $provider_class->provider_service_name ) { + $provider = $provider_class; + } + } + + if ( ! $provider ) { + return new WP_Error( 'provider_class_required', esc_html__( 'Provider class not found.', 'classifai' ) ); + } + + return $provider; +} diff --git a/includes/Classifai/Services/ImageProcessing.php b/includes/Classifai/Services/ImageProcessing.php index 7fd8d7830..9f04ac1ee 100644 --- a/includes/Classifai/Services/ImageProcessing.php +++ b/includes/Classifai/Services/ImageProcessing.php @@ -9,8 +9,8 @@ use WP_REST_Server; use WP_REST_Request; use WP_Error; -use function Classifai\attachment_is_pdf; use function Classifai\get_asset_info; +use function Classifai\find_provider_class; class ImageProcessing extends Service { @@ -51,15 +51,18 @@ public function enqueue_media_scripts() { true ); - wp_add_inline_script( - 'classifai-media-script', - 'const classifaiMediaVars = ' . wp_json_encode( - array( - 'enabledAltTextFields' => $this->provider_classes[0]->get_alt_text_settings() ? $this->provider_classes[0]->get_alt_text_settings() : array(), - ) - ), - 'before' - ); + $provider = find_provider_class( $this->provider_classes, 'Computer Vision' ); + if ( ! is_wp_error( $provider ) ) { + wp_add_inline_script( + 'classifai-media-script', + 'const classifaiMediaVars = ' . wp_json_encode( + array( + 'enabledAltTextFields' => $provider->get_alt_text_settings() ? $provider->get_alt_text_settings() : array(), + ) + ), + 'before' + ); + } } /** @@ -220,7 +223,6 @@ public function computer_vision_endpoint_callback( $request ) { $attachment_id = $request->get_param( 'id' ); $custom_atts = $request->get_attributes(); $route_to_call = empty( $custom_atts['args']['route'] ) ? false : strtolower( $custom_atts['args']['route'][0] ); - $provider = ''; // Check to be sure the post both exists and is an attachment. if ( ! get_post( $attachment_id ) || 'attachment' !== get_post_type( $attachment_id ) ) { @@ -234,15 +236,11 @@ public function computer_vision_endpoint_callback( $request ) { } // Find the right provider class. - foreach ( $this->provider_classes as $provider_class ) { - if ( 'Computer Vision' === $provider_class->provider_service_name ) { - $provider = $provider_class; - } - } + $provider = find_provider_class( $this->provider_classes, 'Computer Vision' ); // Ensure we have a provider class. Should never happen but :shrug: - if ( ! $provider ) { - return new WP_Error( 'provider_class_required', esc_html__( 'Provider class not found.', 'classifai' ) ); + if ( is_wp_error( $provider ) ) { + return $provider; } // Call the provider endpoint function @@ -305,18 +303,12 @@ public function computer_vision_endpoint_permissions_check( WP_REST_Request $req * @return \WP_REST_Response|WP_Error */ public function generate_image( WP_REST_Request $request ) { - $provider = ''; - // Find the right provider class. - foreach ( $this->provider_classes as $provider_class ) { - if ( 'DALL·E' === $provider_class->provider_service_name ) { - $provider = $provider_class; - } - } + $provider = find_provider_class( $this->provider_classes, 'DALL·E' ); // Ensure we have a provider class. Should never happen but :shrug: - if ( ! $provider ) { - return new WP_Error( 'provider_class_required', esc_html__( 'Provider class not found.', 'classifai' ) ); + if ( is_wp_error( $provider ) ) { + return $provider; } return rest_ensure_response( diff --git a/includes/Classifai/Services/LanguageProcessing.php b/includes/Classifai/Services/LanguageProcessing.php index 9da9d5b85..2e6de8460 100644 --- a/includes/Classifai/Services/LanguageProcessing.php +++ b/includes/Classifai/Services/LanguageProcessing.php @@ -6,6 +6,7 @@ namespace Classifai\Services; use Classifai\Admin\SavePostHandler; +use function Classifai\find_provider_class; use WP_REST_Server; use WP_REST_Request; use WP_Error; @@ -174,19 +175,14 @@ public function generate_post_tags_permissions_check( WP_REST_Request $request ) * @return \WP_REST_Response|WP_Error */ public function generate_post_excerpt( WP_REST_Request $request ) { - $post_id = $request->get_param( 'id' ); - $provider = ''; + $post_id = $request->get_param( 'id' ); // Find the right provider class. - foreach ( $this->provider_classes as $provider_class ) { - if ( 'ChatGPT' === $provider_class->provider_service_name ) { - $provider = $provider_class; - } - } + $provider = find_provider_class( $this->provider_classes, 'DALL·E' ); // Ensure we have a provider class. Should never happen but :shrug: - if ( ! $provider ) { - return new WP_Error( 'provider_class_required', esc_html__( 'Provider class not found.', 'classifai' ) ); + if ( is_wp_error( $provider ) ) { + return $provider; } return rest_ensure_response( $provider->rest_endpoint_callback( $post_id, 'excerpt' ) ); diff --git a/includes/Classifai/Services/Personalizer.php b/includes/Classifai/Services/Personalizer.php index 0ac87582c..5c127b620 100644 --- a/includes/Classifai/Services/Personalizer.php +++ b/includes/Classifai/Services/Personalizer.php @@ -5,6 +5,7 @@ namespace Classifai\Services; +use function Classifai\find_provider_class; use WP_REST_Server; use WP_REST_Request; use WP_Error; @@ -68,8 +69,13 @@ public function ajax_render_recommended_content() { } } - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - echo $this->provider_classes[0]->render_recommended_content( $attributes ); + $provider = find_provider_class( $this->provider_classes, 'Personalizer' ); + + if ( ! is_wp_error( $provider ) ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $provider->render_recommended_content( $attributes ); + } + exit(); } @@ -128,7 +134,6 @@ public function reward_endpoint_callback( WP_REST_Request $request ) { $event_id = $request->get_param( 'eventId' ); $reward = ( '1' === $request->get_param( 'rewarded' ) ) ? 1 : 0; $route = $request->get_param( 'route' ) ?? false; - $provider = ''; // If no args, respond 404. if ( false === $route ) { @@ -141,15 +146,11 @@ public function reward_endpoint_callback( WP_REST_Request $request ) { } // Find the right provider class. - foreach ( $this->provider_classes as $provider_class ) { - if ( 'Personalizer' === $provider_class->provider_service_name ) { - $provider = $provider_class; - } - } + $provider = find_provider_class( $this->provider_classes, 'Personalizer' ); // Ensure we have a provider class. Should never happen but :shrug: - if ( ! $provider ) { - return new WP_Error( 'provider_class_required', esc_html__( 'Provider class not found.', 'classifai' ) ); + if ( is_wp_error( $provider ) ) { + return $provider; } // Send reward to personalizer. diff --git a/includes/Classifai/Services/Service.php b/includes/Classifai/Services/Service.php index dedef7ef2..f49564b2a 100644 --- a/includes/Classifai/Services/Service.php +++ b/includes/Classifai/Services/Service.php @@ -5,6 +5,7 @@ namespace Classifai\Services; +use function Classifai\find_provider_class; use WP_Error; abstract class Service { @@ -137,7 +138,12 @@ public function render_settings_page() { submit_button(); ?> - provider_classes[0] ) && ! empty( $this->provider_classes[0]->can_register() ) ) : ?> + provider_classes, 'Natural Language Understanding' ); + + if ( ! is_wp_error( $provider ) && ! empty( $provider->can_register() ) ) : + ?>
Date: Thu, 11 May 2023 14:59:34 -0600 Subject: [PATCH 2/6] Fix fatal errors when no providers are found in a service --- includes/Classifai/Helpers.php | 11 +++++++++-- includes/Classifai/Services/Service.php | 5 +++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/includes/Classifai/Helpers.php b/includes/Classifai/Helpers.php index 87a157ef9..27c8b5dd2 100644 --- a/includes/Classifai/Helpers.php +++ b/includes/Classifai/Helpers.php @@ -44,9 +44,16 @@ function get_plugin_settings( $service = '', $provider = '' ) { return []; } + // Ensure we have at least one provider. + $providers = $service_manager->service_classes[ $service ]->provider_classes; + + if ( empty( $providers ) ) { + return []; + } + // If we want settings for a specific provider, find the proper provider service. if ( ! empty( $provider ) ) { - foreach ( $service_manager->service_classes[ $service ]->provider_classes as $provider_class ) { + foreach ( $providers as $provider_class ) { if ( $provider_class->provider_service_name === $provider ) { return $provider_class->get_settings(); } @@ -56,7 +63,7 @@ function get_plugin_settings( $service = '', $provider = '' ) { } /** @var Provider $provider An instance or extension of the provider abstract class. */ - $provider = $service_manager->service_classes[ $service ]->provider_classes[0]; + $provider = $providers[0]; return $provider->get_settings(); } diff --git a/includes/Classifai/Services/Service.php b/includes/Classifai/Services/Service.php index f49564b2a..9d66009e2 100644 --- a/includes/Classifai/Services/Service.php +++ b/includes/Classifai/Services/Service.php @@ -107,7 +107,8 @@ public function get_display_name() { * Render the start of a settings page. The rest is added by the providers */ public function render_settings_page() { - $active_tab = isset( $_GET['provider'] ) ? sanitize_text_field( $_GET['provider'] ) : $this->provider_classes[0]->get_settings_section(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $active_tab = $this->provider_classes ? $this->provider_classes[0]->get_settings_section() : ''; + $active_tab = isset( $_GET['provider'] ) ? sanitize_text_field( $_GET['provider'] ) : $active_tab; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $base_url = add_query_arg( array( 'page' => 'classifai', @@ -140,7 +141,7 @@ public function render_settings_page() { provider_classes, 'Natural Language Understanding' ); + $provider = find_provider_class( $this->provider_classes ?? [], 'Natural Language Understanding' ); if ( ! is_wp_error( $provider ) && ! empty( $provider->can_register() ) ) : ?> From 21af1a4e5f3d90ea9043c65dcd48fefcd12df94c Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Thu, 11 May 2023 15:04:10 -0600 Subject: [PATCH 3/6] Fix warnings in the onboarding flow --- includes/Classifai/Admin/Onboarding.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/includes/Classifai/Admin/Onboarding.php b/includes/Classifai/Admin/Onboarding.php index 5f2d29130..b96ebc2cb 100644 --- a/includes/Classifai/Admin/Onboarding.php +++ b/includes/Classifai/Admin/Onboarding.php @@ -424,6 +424,10 @@ public function get_features() { $service_slug = $service->get_menu_slug(); $features = array(); + if ( empty( $service->provider_classes ) ) { + continue; + } + foreach ( $service->provider_classes as $provider_class ) { $options = $provider_class->get_onboarding_options(); if ( ! empty( $options ) && ! empty( $options['features'] ) ) { @@ -458,6 +462,10 @@ public function get_providers() { $providers = []; foreach ( $service_manager->service_classes as $service ) { + if ( empty( $service->provider_classes ) ) { + continue; + } + foreach ( $service->provider_classes as $provider_class ) { $providers[ $provider_class->get_option_name() ] = $provider_class; } From 7e78b825b591d7f3e3a8bfd5d7fcbb79b41428a7 Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Thu, 11 May 2023 15:10:22 -0600 Subject: [PATCH 4/6] Output message if no providers are found. Fix a few more warnings --- includes/Classifai/Services/ImageProcessing.php | 6 +++--- includes/Classifai/Services/LanguageProcessing.php | 2 +- includes/Classifai/Services/Personalizer.php | 4 ++-- includes/Classifai/Services/Service.php | 12 ++++++++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/includes/Classifai/Services/ImageProcessing.php b/includes/Classifai/Services/ImageProcessing.php index 9f04ac1ee..31ace8b49 100644 --- a/includes/Classifai/Services/ImageProcessing.php +++ b/includes/Classifai/Services/ImageProcessing.php @@ -51,7 +51,7 @@ public function enqueue_media_scripts() { true ); - $provider = find_provider_class( $this->provider_classes, 'Computer Vision' ); + $provider = find_provider_class( $this->provider_classes ?? [], 'Computer Vision' ); if ( ! is_wp_error( $provider ) ) { wp_add_inline_script( 'classifai-media-script', @@ -236,7 +236,7 @@ public function computer_vision_endpoint_callback( $request ) { } // Find the right provider class. - $provider = find_provider_class( $this->provider_classes, 'Computer Vision' ); + $provider = find_provider_class( $this->provider_classes ?? [], 'Computer Vision' ); // Ensure we have a provider class. Should never happen but :shrug: if ( is_wp_error( $provider ) ) { @@ -304,7 +304,7 @@ public function computer_vision_endpoint_permissions_check( WP_REST_Request $req */ public function generate_image( WP_REST_Request $request ) { // Find the right provider class. - $provider = find_provider_class( $this->provider_classes, 'DALL·E' ); + $provider = find_provider_class( $this->provider_classes ?? [], 'DALL·E' ); // Ensure we have a provider class. Should never happen but :shrug: if ( is_wp_error( $provider ) ) { diff --git a/includes/Classifai/Services/LanguageProcessing.php b/includes/Classifai/Services/LanguageProcessing.php index 2e6de8460..88c41085a 100644 --- a/includes/Classifai/Services/LanguageProcessing.php +++ b/includes/Classifai/Services/LanguageProcessing.php @@ -178,7 +178,7 @@ public function generate_post_excerpt( WP_REST_Request $request ) { $post_id = $request->get_param( 'id' ); // Find the right provider class. - $provider = find_provider_class( $this->provider_classes, 'DALL·E' ); + $provider = find_provider_class( $this->provider_classes ?? [], 'DALL·E' ); // Ensure we have a provider class. Should never happen but :shrug: if ( is_wp_error( $provider ) ) { diff --git a/includes/Classifai/Services/Personalizer.php b/includes/Classifai/Services/Personalizer.php index 5c127b620..67e187733 100644 --- a/includes/Classifai/Services/Personalizer.php +++ b/includes/Classifai/Services/Personalizer.php @@ -69,7 +69,7 @@ public function ajax_render_recommended_content() { } } - $provider = find_provider_class( $this->provider_classes, 'Personalizer' ); + $provider = find_provider_class( $this->provider_classes ?? [], 'Personalizer' ); if ( ! is_wp_error( $provider ) ) { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped @@ -146,7 +146,7 @@ public function reward_endpoint_callback( WP_REST_Request $request ) { } // Find the right provider class. - $provider = find_provider_class( $this->provider_classes, 'Personalizer' ); + $provider = find_provider_class( $this->provider_classes ?? [], 'Personalizer' ); // Ensure we have a provider class. Should never happen but :shrug: if ( is_wp_error( $provider ) ) { diff --git a/includes/Classifai/Services/Service.php b/includes/Classifai/Services/Service.php index 9d66009e2..e58e6975a 100644 --- a/includes/Classifai/Services/Service.php +++ b/includes/Classifai/Services/Service.php @@ -123,14 +123,22 @@ public function render_settings_page() { ?>

display_name ); ?>

- provider_classes ) ) : ?> + + provider_classes ) ) { + echo '

' . esc_html__( 'No providers available for this service.', 'classifai' ) . '

'; + return; + } + ?> + - + +
Date: Thu, 11 May 2023 21:16:57 -0600 Subject: [PATCH 5/6] Fix wrong Provider name. Thanks tests --- includes/Classifai/Services/LanguageProcessing.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/Classifai/Services/LanguageProcessing.php b/includes/Classifai/Services/LanguageProcessing.php index 88c41085a..78068d848 100644 --- a/includes/Classifai/Services/LanguageProcessing.php +++ b/includes/Classifai/Services/LanguageProcessing.php @@ -178,7 +178,7 @@ public function generate_post_excerpt( WP_REST_Request $request ) { $post_id = $request->get_param( 'id' ); // Find the right provider class. - $provider = find_provider_class( $this->provider_classes ?? [], 'DALL·E' ); + $provider = find_provider_class( $this->provider_classes ?? [], 'ChatGPT' ); // Ensure we have a provider class. Should never happen but :shrug: if ( is_wp_error( $provider ) ) { From 658794c7d563377e566abeea214da6a2c2ec222d Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Thu, 18 May 2023 10:43:55 -0600 Subject: [PATCH 6/6] Ensure we properly close div tags when we return early --- includes/Classifai/Services/Service.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/Classifai/Services/Service.php b/includes/Classifai/Services/Service.php index e58e6975a..dfc23902b 100644 --- a/includes/Classifai/Services/Service.php +++ b/includes/Classifai/Services/Service.php @@ -127,6 +127,7 @@ public function render_settings_page() { provider_classes ) ) { echo '

' . esc_html__( 'No providers available for this service.', 'classifai' ) . '

'; + echo '
'; return; } ?>