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

Ensure post type and taxonomy options are filterable via existing filters in the new React settings #831

Merged
merged 6 commits into from
Dec 11, 2024
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
72 changes: 65 additions & 7 deletions includes/Classifai/Admin/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
use Classifai\Features\Classification;
use Classifai\Services\ServicesManager;

use Classifai\Taxonomy\TaxonomyFactory;
use function Classifai\get_asset_info;
use function Classifai\get_plugin;
use function Classifai\get_post_types_for_language_settings;
use function Classifai\get_services_menu;
use function Classifai\get_post_statuses_for_language_settings;
use function Classifai\is_elasticpress_installed;
Expand Down Expand Up @@ -84,14 +86,27 @@ public function admin_enqueue_scripts( $hook_suffix ) {

wp_set_script_translations( 'classifai-settings', 'classifai' );

$post_types = get_post_types_for_language_settings();
$excerpt_post_types = array();
$post_type_options = array();
foreach ( $post_types as $post_type ) {
$post_type_options[ $post_type->name ] = $post_type->label;
if ( post_type_supports( $post_type->name, 'excerpt' ) ) {
$excerpt_post_types[ $post_type->name ] = $post_type->label;
}
}

$data = array(
'features' => $this->get_features(),
'services' => get_services_menu(),
'settings' => $this->get_settings(),
'dashboardUrl' => admin_url( '/' ),
'nonce' => wp_create_nonce( 'classifai-previewer-action' ),
'postStatuses' => get_post_statuses_for_language_settings(),
'isEPinstalled' => is_elasticpress_installed(),
'features' => $this->get_features(),
'services' => get_services_menu(),
'settings' => $this->get_settings(),
'dashboardUrl' => admin_url( '/' ),
'nonce' => wp_create_nonce( 'classifai-previewer-action' ),
'postTypes' => $post_type_options,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be moved under features, but since we are using the get_post_types_for_language_settings helper function to retrieve post types, it has been kept here to continue using the same filter and avoid introducing unnecessary loop in the features data.

'excerptPostTypes' => $excerpt_post_types,
'postStatuses' => get_post_statuses_for_language_settings(),
'isEPinstalled' => is_elasticpress_installed(),
'nluTaxonomies' => $this->get_nlu_taxonomies(),
);

wp_add_inline_script(
Expand Down Expand Up @@ -142,6 +157,7 @@ public function get_features( bool $with_instance = false ): array {
return $services;
}

$post_types = get_post_types_for_language_settings();
foreach ( $service_manager->service_classes as $service ) {
$services[ $service->get_menu_slug() ] = array();

Expand All @@ -151,13 +167,55 @@ public function get_features( bool $with_instance = false ): array {
'providers' => $feature->get_providers(),
'roles' => $feature->get_roles(),
'enable_description' => $feature->get_enable_description(),
'taxonomies' => $feature->get_taxonomies(),
);

// Add taxonomies under post types for language processing features to allow filtering by post type.
if ( 'language_processing' === $service->get_menu_slug() && ! empty( $post_types ) ) {
$post_types_taxonomies = array();
foreach ( $post_types as $post_type ) {
$post_types_taxonomies[ $post_type->name ] = $feature->get_taxonomies( [ $post_type->name ] );
}
$services[ $service->get_menu_slug() ][ $feature::ID ]['taxonomiesByPostTypes'] = $post_types_taxonomies;
}
}
}

return $services;
}

/**
* Return the list of NLU taxonomies for the Classification feature settings.
*
* @return array
*/
public function get_nlu_taxonomies(): array {
$taxonomies = [];
$taxonomy_factory = new TaxonomyFactory();
$nlu_taxonomies = $taxonomy_factory->get_supported_taxonomies();
foreach ( $nlu_taxonomies as $taxonomy ) {
$taxonomy_instance = $taxonomy_factory->build( $taxonomy );
if ( ! $taxonomy_instance ) {
continue;
}

$taxonomies[ $taxonomy_instance->get_name() ] = $taxonomy_instance->get_singular_label();
}

/**
* Filter IBM Watson NLU taxonomies shown in settings.
*
* @since x.x.x
* @hook classifai_settings_ibm_watson_nlu_taxonomies
*
* @param {array} $taxonomies Array of IBM Watson NLU taxonomies.
*
* @return {array} Array of taxonomies.
*/
return apply_filters( 'classifai_settings_ibm_watson_nlu_taxonomies', $taxonomies );
}


/**
* Get the settings.
*
Expand Down
32 changes: 1 addition & 31 deletions includes/Classifai/Features/Classification.php
Original file line number Diff line number Diff line change
Expand Up @@ -1015,37 +1015,7 @@ public function get_supported_taxonomies( array $post_types = [] ): array {
}
}

$taxonomies = get_taxonomies( [], 'objects' );
$taxonomies = array_filter( $taxonomies, 'is_taxonomy_viewable' );
$supported = [];

foreach ( $taxonomies as $taxonomy ) {
// Remove this taxonomy if it doesn't support at least one of our post types.
if (
(
! empty( $supported_post_types ) &&
empty( array_intersect( $supported_post_types, $taxonomy->object_type ) )
) ||
'post_format' === $taxonomy->name
) {
continue;
}

$supported[ $taxonomy->name ] = $taxonomy->labels->singular_name;
}

/**
* Filter taxonomies shown in settings.
*
* @since 3.0.0
* @hook classifai_feature_classification_setting_taxonomies
*
* @param {array} $supported Array of supported taxonomies.
* @param {object} $this Current instance of the class.
*
* @return {array} Array of taxonomies.
*/
return apply_filters( 'classifai_' . static::ID . '_setting_taxonomies', $supported, $this );
return $this->get_taxonomies( $supported_post_types );
}

/**
Expand Down
40 changes: 40 additions & 0 deletions includes/Classifai/Features/Feature.php
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,46 @@ public function get_supported_post_statuses(): array {
return $post_statuses;
}

/**
* Return the list of taxonomies for the feature settings.
*
* @param array $post_types Array of post types to filter taxonomies by, leave empty to get all taxonomies.
* @return array
*/
public function get_taxonomies( array $post_types = [] ): array {
$taxonomies = get_taxonomies( [], 'objects' );
$taxonomies = array_filter( $taxonomies, 'is_taxonomy_viewable' );
$supported = [];

foreach ( $taxonomies as $taxonomy ) {
// Remove this taxonomy if it doesn't support at least one of our post types.
if (
(
! empty( $post_types ) &&
empty( array_intersect( $post_types, $taxonomy->object_type ) )
) ||
'post_format' === $taxonomy->name
) {
continue;
}

$supported[ $taxonomy->name ] = $taxonomy->labels->singular_name;
}

/**
* Filter taxonomies shown in settings.
*
* @since 3.0.0
* @hook classifai_{feature}_setting_taxonomies
*
* @param {array} $supported Array of supported taxonomies.
* @param {object} $this Current instance of the class.
*
* @return {array} Array of taxonomies.
*/
return apply_filters( 'classifai_' . static::ID . '_setting_taxonomies', $supported, $this );
}

/**
* Returns array of instances of provider classes registered for the service.
*
Expand Down
28 changes: 28 additions & 0 deletions includes/Classifai/Features/ImageTagsGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,34 @@ public function sanitize_default_feature_settings( array $new_settings ): array
return $new_settings;
}

/**
* Return the list of Attachment taxonomies for the feature settings.
*
* @param array $object_types Array of object types to filter taxonomies by, not in use.
* @return array
*/
public function get_taxonomies( array $object_types = [] ): array {
$attachment_taxonomies = get_object_taxonomies( 'attachment', 'objects' );
$taxonomies = [];

foreach ( $attachment_taxonomies as $name => $taxonomy ) {
$taxonomies[ $name ] = $taxonomy->label;
}

/**
* Filter taxonomies shown in settings.
*
* @since x.x.x
* @hook classifai_feature_image_tags_generator_setting_taxonomies
*
* @param {array} $supported Array of supported image taxonomies.
* @param {object} $this Current instance of the class.
*
* @return {array} Array of taxonomies.
*/
return apply_filters( 'classifai_' . static::ID . '_setting_taxonomies', $taxonomies, $this );
}

/**
* Generates feature setting data required for migration from
* ClassifAI < 3.0.0 to 3.0.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { store as noticesStore } from '@wordpress/notices';
*/
import { SettingsRow } from '../settings-row';
import { STORE_NAME } from '../../data/store';
import { isFeatureActive, usePostTypes } from '../../utils/utils';
import { isFeatureActive } from '../../utils/utils';
import { NLUFeatureSettings } from './nlu-feature';
import {
AzureOpenAIEmbeddingsResults,
Expand Down Expand Up @@ -132,8 +132,7 @@ export const ClassificationSettings = () => {
);
const isConfigured = isFeatureActive( featureSettings );
const { setFeatureSettings } = useDispatch( STORE_NAME );
const { postTypesSelectOptions } = usePostTypes();
const { postStatuses } = window.classifAISettings;
const { postTypes, postStatuses } = window.classifAISettings;
const { createSuccessNotice } = useDispatch( noticesStore );

const previewerContextData = {
Expand Down Expand Up @@ -272,16 +271,15 @@ export const ClassificationSettings = () => {
) }
className="settings-allowed-post-types"
>
{ postTypesSelectOptions.map( ( option ) => {
const { value: key, label } = option;
{ Object.keys( postTypes || {} ).map( ( key ) => {
return (
<CheckboxControl
id={ key }
key={ key }
checked={
featureSettings.post_types?.[ key ] === key
}
label={ label }
label={ postTypes?.[ key ] }
onChange={ ( value ) => {
setFeatureSettings( {
post_types: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
import { SettingsRow } from '../settings-row';
import { STORE_NAME } from '../../data/store';
import { PromptRepeater } from './prompt-repeater';
import { usePostTypes } from '../../utils/utils';

/**
* Component for Excerpt Generation feature settings.
Expand All @@ -27,7 +26,7 @@ export const ExcerptGenerationSettings = () => {
const featureSettings = useSelect( ( select ) =>
select( STORE_NAME ).getFeatureSettings()
);
const { excerptPostTypesOptions } = usePostTypes();
const { excerptPostTypes } = window.classifAISettings;
const { setFeatureSettings } = useDispatch( STORE_NAME );
const setPromts = ( prompts ) => {
setFeatureSettings( {
Expand Down Expand Up @@ -57,16 +56,15 @@ export const ExcerptGenerationSettings = () => {
) }
className="settings-allowed-post-types"
>
{ ( excerptPostTypesOptions || [] ).map( ( option ) => {
const { value: key, label } = option;
{ Object.keys( excerptPostTypes || {} ).map( ( key ) => {
return (
<CheckboxControl
id={ key }
key={ key }
checked={
featureSettings.post_types?.[ key ] === key
}
label={ label }
label={ excerptPostTypes?.[ key ] }
onChange={ ( value ) => {
setFeatureSettings( {
post_types: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { __ } from '@wordpress/i18n';
*/
import { SettingsRow } from '../settings-row';
import { STORE_NAME } from '../../data/store';
import { useFeatureContext } from '../feature-settings/context';
import { getFeature } from '../../utils/utils';

/**
* Component for the Image Tag Generator feature settings.
Expand All @@ -20,20 +22,17 @@ import { STORE_NAME } from '../../data/store';
* @return {React.ReactElement} ImageTagGeneratorSettings component.
*/
export const ImageTagGeneratorSettings = () => {
const { featureName } = useFeatureContext();
const featureSettings = useSelect( ( select ) =>
select( STORE_NAME ).getFeatureSettings()
);
const { setFeatureSettings } = useDispatch( STORE_NAME );
const { taxonomies } = getFeature( featureName );

const attachmentTaxonomies = useSelect( ( select ) => {
const { getTaxonomies } = select( 'core' );
return getTaxonomies( { type: 'attachment' } ) || [];
}, [] );

const options = attachmentTaxonomies.map( ( taxonomy ) => {
const options = Object.keys( taxonomies || {} ).map( ( slug ) => {
return {
value: taxonomy.slug,
label: taxonomy.labels.name,
value: slug,
label: taxonomies[ slug ],
};
} );
return (
Expand Down
Loading
Loading