Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
26 changes: 14 additions & 12 deletions includes/Admin/Forms/Admin_Form_Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@
'form_settings_key' => '',
'post_id' => 0,
'shortcodes' => [],
// [ [ 'name' => 'wpuf_form', 'type' => 'profile' ], [ 'name' => 'wpuf_form', 'type' => 'registration' ] ]

Check warning on line 46 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

This comment is 56% valid code; is this commented out code?
];
$this->settings = wp_parse_args( $settings, $defaults );
// set post data to global $post
$post = get_post( $this->settings['post_id'] );

Check failure on line 50 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Overriding WordPress globals is prohibited. Found assignment to $post
// if we have an existing post, then let's start
if ( ! empty( $post->ID ) ) {
add_action( 'in_admin_header', 'wpuf_remove_admin_notices' );
Expand Down Expand Up @@ -125,15 +125,15 @@

$single_objects = apply_filters(
'wpuf_single_form_field',
[

Check failure on line 128 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Multi-line function call not indented correctly; expected 12 spaces but found 16
'post_title',

Check failure on line 129 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 20 spaces but found 16
'post_content',

Check failure on line 130 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 20 spaces but found 16
'post_excerpt',

Check failure on line 131 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 20 spaces but found 16
'featured_image',

Check failure on line 132 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 20 spaces but found 16
'user_login',

Check failure on line 133 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 20 spaces but found 16
'first_name',

Check failure on line 134 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 20 spaces but found 16
'last_name',

Check failure on line 135 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 20 spaces but found 16
'nickname',

Check failure on line 136 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 20 spaces but found 16
'user_email',
'user_url',
'user_bio',
Expand Down Expand Up @@ -338,7 +338,7 @@
'last_column_warn_msg' => __( 'This field must contain at least one column', 'wp-user-frontend' ),
'is_a_pro_feature' => __( 'is a pro feature', 'wp-user-frontend' ),
'pro_feature_msg' => __(
'<p class="wpuf-text-gray-500 wpuf-font-medium wpuf-text-xl">Please upgrade to the Pro version to unlock all these awesome features</p>',

Check warning on line 341 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Translatable string should not be wrapped in HTML. Found: '<p class="wpuf-text-gray-500 wpuf-font-medium wpuf-text-xl">Please upgrade to the Pro version to unlock all these awesome features</p>'
'wp-user-frontend'
),
'upgrade_to_pro' => __( 'Upgrade to PRO', 'wp-user-frontend' ),
Expand All @@ -362,15 +362,15 @@
*/
public static function save_form( $data ) {
$saved_wpuf_inputs = [];
wp_update_post( [ 'ID' => $data['form_id'], 'post_status' => 'publish', 'post_title' => $data['post_title'] ] );

Check warning on line 365 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

When a multi-item array uses associative keys, each value should start on a new line.
$existing_wpuf_input_ids = get_children( [
'post_parent' => $data['form_id'],

Check warning on line 367 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Found precision alignment of 1 spaces.
'post_status' => 'publish',

Check warning on line 368 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Found precision alignment of 1 spaces.
'post_type' => 'wpuf_input',

Check warning on line 369 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Found precision alignment of 1 spaces.
'numberposts' => '-1',

Check warning on line 370 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Found precision alignment of 1 spaces.
'orderby' => 'menu_order',

Check warning on line 371 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Found precision alignment of 1 spaces.
'order' => 'ASC',

Check warning on line 372 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Found precision alignment of 1 spaces.
'fields' => 'ids',

Check warning on line 373 in includes/Admin/Forms/Admin_Form_Builder.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Found precision alignment of 1 spaces.
] );
$new_wpuf_input_ids = [];
if ( ! empty( $data['form_fields'] ) ) {
Expand Down Expand Up @@ -517,21 +517,21 @@
return $form_fields;
}

// Built-in taxonomies that should always be available
$builtin_taxonomies = array( 'category', 'post_tag' );
// Get free taxonomies (built-in + ACF taxonomies)
$free_taxonomies = wpuf_get_free_taxonomies();

// Filter out custom taxonomy fields
// Filter out custom taxonomy fields (excluding ACF taxonomies)
$filtered_fields = array();

foreach ( $form_fields as $field ) {
// Skip custom taxonomy fields when pro is not active
// Skip custom taxonomy fields when pro is not active (but keep ACF taxonomies)
if ( isset( $field['input_type'] ) && $field['input_type'] === 'taxonomy' ) {
if ( isset( $field['name'] ) && ! in_array( $field['name'], $builtin_taxonomies, true ) ) {
continue; // Skip this custom taxonomy field
if ( isset( $field['name'] ) && ! in_array( $field['name'], $free_taxonomies, true ) ) {
continue; // Skip this custom taxonomy field (not ACF)
}
}

// Keep all other fields including built-in taxonomies
// Keep all other fields including built-in and ACF taxonomies
$filtered_fields[] = $field;
}

Expand All @@ -549,7 +549,8 @@
if ( wpuf_is_pro_active() ) {
return false;
}
$builtin = [ 'category', 'post_tag' ];
// Get free taxonomies (built-in + ACF taxonomies)
$free_taxonomies = wpuf_get_free_taxonomies();
$stack = is_array($original_fields) ? $original_fields : [];
while ( $stack ) {
$f = array_pop( $stack );
Expand All @@ -568,7 +569,7 @@
}
if ( isset( $f['input_type'] ) && $f['input_type'] === 'taxonomy' ) {
$slug = $f['name'] ?? ($f['taxonomy'] ?? null);
if ( $slug && ! in_array( $slug, $builtin, true ) ) {
if ( $slug && ! in_array( $slug, $free_taxonomies, true ) ) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Verify the fallback to taxonomy key is necessary.

Line 571 extracts the taxonomy slug with $f['name'] ?? ($f['taxonomy'] ?? null), falling back to the taxonomy key. However, the other methods (filter_pro_taxonomy_fields and get_hidden_taxonomy_ids) only check $field['name'].

Ensure this fallback is intentional and that taxonomy fields can indeed have the slug under either key, or consider aligning the extraction logic across all three methods for consistency.


🏁 Script executed:

#!/bin/bash
# Description: Search for taxonomy field structures to verify which keys are used for the taxonomy slug

# Search for where taxonomy fields are created/structured
rg -n -C3 'input_type.*taxonomy|taxonomy.*input_type' --type=php

# Look for assignments to taxonomy field 'name' or 'taxonomy' keys
ast-grep --pattern $'$field[\'name\'] = $_'
ast-grep --pattern $'$field[\'taxonomy\'] = $_'

Length of output: 16231



🏁 Script executed:

#!/bin/bash
# Search for where 'taxonomy' key is actually assigned to fields
rg -n -C2 "\['taxonomy'\]\s*=" --type=php | head -50

# Also search for field definitions that might have taxonomy key
rg -n "taxonomy.*=>|'taxonomy'" --type=php -C2 | grep -E "\['taxonomy'\]|'taxonomy'\s*=>" | head -30

Length of output: 4029



🏁 Script executed:

#!/bin/bash
# Search for how nested/column fields are constructed to see which keys they preserve
rg -n -B5 -A5 "column_field|inner.*field" includes/Admin/Forms/Admin_Form_Builder.php | head -60

# Also check the actual field structure in the stack-based traversal
rg -n -B10 -A10 "has_filtered_taxonomies" includes/Admin/Forms/Admin_Form_Builder.php

Length of output: 3215


Align the taxonomy slug extraction with other methods for consistency.

Line 571 extracts the slug with a fallback to $f['taxonomy'], but filter_pro_taxonomy_fields (line 528) and get_hidden_taxonomy_ids (line 607) only check $field['name']. Since all observed field definitions consistently populate the name key, the fallback appears unnecessary. Either document why the taxonomy key fallback is needed for nested fields, or remove it to align with the other methods.

🤖 Prompt for AI Agents
In includes/Admin/Forms/Admin_Form_Builder.php around lines 570 to 572, the code
falls back to $f['taxonomy'] when extracting the slug but other methods
(filter_pro_taxonomy_fields at line 528 and get_hidden_taxonomy_ids at line 607)
only use $field['name']; remove the unnecessary fallback and read the slug
strictly from $f['name'] (e.g., $slug = $f['name'] ?? null), update the
conditional accordingly, and add a brief inline comment if you believe nested
fields require a different key so future readers know why only 'name' is used.

return true;
}
}
Expand All @@ -590,7 +591,8 @@
}

$hidden_ids = array();
$builtin_taxonomies = array( 'category', 'post_tag' );
// Get free taxonomies (built-in + ACF taxonomies)
$free_taxonomies = wpuf_get_free_taxonomies();

// Extract IDs from filtered fields for quick lookup
$filtered_ids = array();
Expand All @@ -600,10 +602,10 @@
}
}

// Find original fields that are custom taxonomy fields and were filtered out
// Find original fields that are custom taxonomy fields and were filtered out (excluding ACF)
foreach ( $original_fields as $field ) {
if ( isset( $field['input_type'] ) && $field['input_type'] === 'taxonomy' ) {
if ( isset( $field['name'] ) && ! in_array( $field['name'], $builtin_taxonomies, true ) ) {
if ( isset( $field['name'] ) && ! in_array( $field['name'], $free_taxonomies, true ) ) {
if ( isset( $field['id'] ) && ! in_array( $field['id'], $filtered_ids, true ) ) {
$hidden_ids[] = $field['id'];
}
Expand Down
16 changes: 8 additions & 8 deletions includes/Fields/Form_Field_Post_Taxonomy.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ public function __construct( $tax_name, $taxonomy, $post_id = null, $user_id = n
* @return bool
*/
public function is_pro() {
// Built-in WordPress taxonomies that are always available
$builtin_taxonomies = array( 'category', 'post_tag' );
// Get free taxonomies (built-in + ACF taxonomies)
$free_taxonomies = wpuf_get_free_taxonomies();

// If this is a custom taxonomy (not built-in) and pro is not active, treat it as a pro feature
if ( ! in_array( $this->tax_name, $builtin_taxonomies, true ) && ! wpuf_is_pro_active() ) {
// If this is a custom taxonomy (not built-in or ACF) and pro is not active, treat it as a pro feature
if ( ! in_array( $this->tax_name, $free_taxonomies, true ) && ! wpuf_is_pro_active() ) {
return true;
}

Expand All @@ -69,12 +69,12 @@ public function is_pro() {
* @return void
*/
public function render( $field_settings, $form_id, $type = 'post', $post_id = null ) {
// Check if this is a custom taxonomy and pro is not active
$builtin_taxonomies = array( 'category', 'post_tag' );
// Check if this is a custom taxonomy and pro is not active (excluding ACF taxonomies)
$free_taxonomies = wpuf_get_free_taxonomies();
$taxonomy_name = isset( $field_settings['name'] ) ? $field_settings['name'] : $this->tax_name;

if ( ! in_array( $taxonomy_name, $builtin_taxonomies, true ) && ! wpuf_is_pro_active() ) {
// Don't render custom taxonomies on frontend when pro is not active
if ( ! in_array( $taxonomy_name, $free_taxonomies, true ) && ! wpuf_is_pro_active() ) {
// Don't render custom taxonomies on frontend when pro is not active (ACF taxonomies are allowed)
return;
}

Expand Down
14 changes: 7 additions & 7 deletions includes/Render_Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -1340,9 +1340,9 @@ private function is_taxonomy_field_gated( $form_field ) {
return false;
}

// Check if this is a custom taxonomy
$builtin_taxonomies = apply_filters( 'wpuf_builtin_taxonomies_free', array( 'category', 'post_tag' ) );
return ! in_array( $form_field['name'], $builtin_taxonomies, true );
// Get free taxonomies (built-in + ACF taxonomies)
$free_taxonomies = wpuf_get_free_taxonomies();
return ! in_array( $form_field['name'], $free_taxonomies, true );
}

/**
Expand All @@ -1352,10 +1352,10 @@ private function is_taxonomy_field_gated( $form_field ) {
* @param int|null $post_id
*/
public function taxonomy( $attr, $post_id, $form_id ) {
// Check if this is a custom taxonomy and pro is not active
$builtin_taxonomies = apply_filters( 'wpuf_builtin_taxonomies_free', array( 'category', 'post_tag' ) );
if ( ! in_array( $attr['name'], $builtin_taxonomies, true ) && ! wpuf_is_pro_active() ) {
// Don't render custom taxonomies when pro is not active
// Check if this is a custom taxonomy and pro is not active (excluding ACF taxonomies)
$free_taxonomies = wpuf_get_free_taxonomies();
if ( ! in_array( $attr['name'], $free_taxonomies, true ) && ! wpuf_is_pro_active() ) {
// Don't render custom taxonomies when pro is not active (ACF taxonomies are allowed)
return;
}

Expand Down
160 changes: 160 additions & 0 deletions wpuf-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5704,3 +5704,163 @@ function wpuf_field_profile_photo_allowed_mimes() {
return apply_filters( 'wpuf_field_profile_photo_allowed_mimes', $profile_photo_mimes );
}
}

/**
* Check if a taxonomy is registered by Advanced Custom Fields (ACF)
*
* ACF taxonomies should be available in the free version as they are user-created
* via ACF, not plugin-specific custom taxonomies.
*
* @since WPUF_SINCE
*
* @param string $taxonomy_name The taxonomy name to check
* @return bool True if taxonomy is registered by ACF, false otherwise
*/
if ( ! function_exists( 'wpuf_is_acf_taxonomy' ) ) {
function wpuf_is_acf_taxonomy( $taxonomy_name ) {
// If taxonomy doesn't exist, it can't be an ACF taxonomy
if ( ! taxonomy_exists( $taxonomy_name ) ) {
return false;
}

// Get the taxonomy object
$taxonomy = get_taxonomy( $taxonomy_name );

if ( ! $taxonomy ) {
return false;
}

// ACF taxonomies typically have these characteristics:
// 1. They are not built-in (_builtin = false)
// 2. They are registered by ACF (check for ACF-specific properties)

// Check if ACF is active
if ( ! class_exists( 'acf' ) ) {
return false;
}

// ACF stores taxonomy configuration in the database
// Check if there's an ACF post type that registered this taxonomy
global $wpdb;

// ACF saves custom taxonomies as posts of type 'acf-taxonomy'
// The taxonomy slug is stored in the serialized post_content, not post_name
// post_name is ACF's internal key like 'taxonomy_69242380c35d7'
$acf_taxonomies = $wpdb->get_results(
"SELECT post_content FROM {$wpdb->posts}
WHERE post_type = 'acf-taxonomy'
AND post_status = 'publish'"
);

if ( ! empty( $acf_taxonomies ) ) {
foreach ( $acf_taxonomies as $acf_tax ) {
// ACF stores the taxonomy configuration as serialized data
$config = maybe_unserialize( $acf_tax->post_content );

// Check if the taxonomy key matches our taxonomy name
if ( is_array( $config ) && isset( $config['taxonomy'] ) && $config['taxonomy'] === $taxonomy_name ) {
return true;
}
}
}

// Additional check: ACF taxonomies often have 'acf' in their labels or registration
// Check if the taxonomy object has ACF-specific metadata
if ( isset( $taxonomy->acf ) || isset( $taxonomy->_builtin ) && ! $taxonomy->_builtin ) {
// Check if registered via ACF by looking for ACF functions
if ( function_exists( 'acf_get_internal_post_type' ) ) {
$internal_types = acf_get_internal_post_type( 'acf-taxonomy', 'names' );
if ( is_array( $internal_types ) && in_array( $taxonomy_name, $internal_types, true ) ) {
return true;
}
}
}

return false;
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

ACF Advanced Custom Fields class bootstrap activation check

💡 Result:

Short answer — use plugin checks first, and fall back to class/function checks. Example (best practice per ACF docs):

  • In admin or after including plugin.php:
    if ( is_plugin_active( 'advanced-custom-fields-pro/acf.php' ) || is_plugin_active( 'advanced-custom-fields/acf.php' ) ) {
    // ACF (or ACF Pro) is active — do nothing / prefer site plugin.
    }

  • If you need to detect at runtime (front-end or bundled ACF fallback), use class_exists() / function_exists():
    if ( class_exists( 'acf' ) || class_exists( 'acf_pro' ) || function_exists( 'acf' ) ) {
    // ACF is available.
    } else {
    // Include/bundle ACF safely (define path, include acf.php, set acf/settings/url, hide admin UI, etc.).
    }

References:

  • ACF official guide: including/bundling and plugin detection. [1]
  • Community guidance (class_exists / is_plugin_active usage). [2]

Sources:
[1] Advanced Custom Fields — How to Include ACF PRO in a Plugin or Theme.
[2] WordPress StackExchange / ACF inclusion examples.


🌐 Web query:

acf_get_internal_post_type ACF function signature documentation

💡 Result:

Signature (ACF ≥6.1):

acf_get_internal_post_type( int|string $id, string $post_type ) : array|false

  • Description: Returns an ACF internal post type as an array, or false on failure. [1]

Source: ACF Internal Post Type functions reference. [1]


🏁 Script executed:

# Search the codebase for calls to wpuf_is_acf_taxonomy to assess call frequency
rg "wpuf_is_acf_taxonomy" --type php -B 2 -A 2

Repository: weDevsOfficial/wp-user-frontend

Length of output: 206


Tighten ACF detection and remove the broken fallback heuristic

The core DB-based detection of ACF taxonomies is correct, but two issues need fixing:

  1. ACF detection should use a fallback chain
    The current check class_exists( 'acf' ) is insufficient. Per ACF best practice, use a fallback chain to handle different ACF versions and loading contexts:
-        if ( ! class_exists( 'acf' ) ) {
+        if ( ! class_exists( 'acf' ) && ! class_exists( 'acf_pro' ) && ! function_exists( 'acf' ) ) {
             return false;
         }
  1. Remove the broken acf_get_internal_post_type() fallback block
    The fallback block calling acf_get_internal_post_type( 'acf-taxonomy', 'names' ) is incorrect. Per ACF docs, acf_get_internal_post_type( int|string $id, string $post_type ) : array|false accepts an $id and $post_type parameter and returns a single post type object (or false), not a list of taxonomy slugs. The current call won't return what the code expects, and the in_array() check will always fail.

Since the preceding DB query already correctly identifies ACF taxonomies, remove the broken heuristic entirely:

-        // Additional check: ACF taxonomies often have 'acf' in their labels or registration
-        // Check if the taxonomy object has ACF-specific metadata
-        if ( isset( $taxonomy->acf ) || isset( $taxonomy->_builtin ) && ! $taxonomy->_builtin ) {
-            // Check if registered via ACF by looking for ACF functions
-            if ( function_exists( 'acf_get_internal_post_type' ) ) {
-                $internal_types = acf_get_internal_post_type( 'acf-taxonomy', 'names' );
-                if ( is_array( $internal_types ) && in_array( $taxonomy_name, $internal_types, true ) ) {
-                    return true;
-                }
-            }
-        }
  1. Performance: cache ACF taxonomy slugs across calls (optional)
    Every call runs a full DB query and unserializes all ACF taxonomy configs. For repeated calls within a request, a static cache improves performance with minimal overhead:
-        $acf_taxonomies = $wpdb->get_results(
-            "SELECT post_content FROM {$wpdb->posts}
-            WHERE post_type = 'acf-taxonomy'
-            AND post_status = 'publish'"
-        );
-
-        if ( ! empty( $acf_taxonomies ) ) {
-            foreach ( $acf_taxonomies as $acf_tax ) {
-                // ACF stores the taxonomy configuration as serialized data
-                $config = maybe_unserialize( $acf_tax->post_content );
-
-                // Check if the taxonomy key matches our taxonomy name
-                if ( is_array( $config ) && isset( $config['taxonomy'] ) && $config['taxonomy'] === $taxonomy_name ) {
-                    return true;
-                }
-            }
-        }
+        static $acf_taxonomy_slugs = null;
+
+        if ( null === $acf_taxonomy_slugs ) {
+            $acf_taxonomy_slugs = [];
+
+            $acf_posts = $wpdb->get_results(
+                "SELECT post_content FROM {$wpdb->posts}
+                 WHERE post_type = 'acf-taxonomy'
+                 AND post_status = 'publish'"
+            );
+
+            foreach ( $acf_posts as $acf_post ) {
+                $config = maybe_unserialize( $acf_post->post_content );
+
+                if ( is_array( $config ) && ! empty( $config['taxonomy'] ) ) {
+                    $acf_taxonomy_slugs[] = $config['taxonomy'];
+                }
+            }
+        }
+
+        if ( in_array( $taxonomy_name, $acf_taxonomy_slugs, true ) ) {
+            return true;
+        }
🤖 Prompt for AI Agents
In wpuf-functions.php around lines 5708 to 5781, tighten ACF detection by
replacing the simple class_exists('acf') check with a fallback chain that checks
for acf(), function_exists('acf_get_instance'), and class_exists('ACF'), then
remove the broken acf_get_internal_post_type() fallback block entirely (it
returns a single post object or false, not an array of taxonomy slugs), and
implement a static cache for the DB-driven discovery of ACF taxonomies so the
query + maybe_unserialize work only once per request; ensure the DB loop remains
the primary detector and short-circuits true when a matching config['taxonomy']
=== $taxonomy_name is found, otherwise return false.


/**
* Get taxonomy object types (post types the taxonomy is associated with)
*
* This works for all taxonomies - built-in, custom, ACF, or any other.
*
* @since WPUF_SINCE
*
* @param string $taxonomy_name The taxonomy name to check
* @return array Array of post type names associated with the taxonomy
*/
if ( ! function_exists( 'wpuf_get_taxonomy_post_types' ) ) {
function wpuf_get_taxonomy_post_types( $taxonomy_name ) {
// If taxonomy doesn't exist, return empty array
if ( ! taxonomy_exists( $taxonomy_name ) ) {
return [];
}

// Get the taxonomy object
$taxonomy = get_taxonomy( $taxonomy_name );

if ( ! $taxonomy ) {
return [];
}

// WordPress stores associated post types in object_type property
if ( isset( $taxonomy->object_type ) && is_array( $taxonomy->object_type ) ) {
return $taxonomy->object_type;
}

return [];
}
}

/**
* Get list of taxonomies that should be available in free version
*
* This includes built-in taxonomies and ACF-registered taxonomies.
*
* @since WPUF_SINCE
*
* @return array Array of taxonomy names that are available in free version
*/
if ( ! function_exists( 'wpuf_get_free_taxonomies' ) ) {
function wpuf_get_free_taxonomies() {
// Built-in taxonomies that are always available
$free_taxonomies = array( 'category', 'post_tag' );

// Allow filtering to add more free taxonomies
//$free_taxonomies = apply_filters( 'wpuf_free_taxonomies', $free_taxonomies );

// Get all registered taxonomies (built-in and custom)
$all_taxonomies = get_taxonomies( array(), 'names' );

foreach ( $all_taxonomies as $taxonomy_name ) {
// Skip if already in free list
if ( in_array( $taxonomy_name, $free_taxonomies, true ) ) {
continue;
}

// Get the post types this taxonomy is associated with
$post_types = wpuf_get_taxonomy_post_types( $taxonomy_name );

// Only allow taxonomies that are associated with 'post' or 'page' in free version
if ( ! empty( $post_types ) ) {
$allowed_post_types = array( 'post', 'page' );
$has_allowed_type = false;

foreach ( $post_types as $post_type ) {
if ( in_array( $post_type, $allowed_post_types, true ) ) {
$has_allowed_type = true;
break;
}
}

// If this taxonomy is for post or page, add it to free list
if ( $has_allowed_type ) {
$free_taxonomies[] = $taxonomy_name;
}
}
}

return $free_taxonomies;
}
}
Loading