HEX
Server: nginx/1.27.1
System: Linux in-4 5.15.0-131-generic #141-Ubuntu SMP Fri Jan 10 21:18:28 UTC 2025 x86_64
User: ilikadirect (1186)
PHP: 7.4.33
Disabled: exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_source
Upload Files
File: /storage/v6964/testingff/public_html/fdfctr/wp-content/plugins/connections/includes/class.meta.php
<?php
/**
 * Metadata API.
 *
 * Provides methods to manage the metadata of the various Connections object types.
 *
 * @package     Connections
 * @subpackage  Meta
 * @copyright   Copyright (c) 2013, Steven A. Zahm
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       0.8
 */

use Connections_Directory\Utility\_;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

/**
 * Class cnMeta
 *
 * @phpcs:disable PEAR.NamingConventions.ValidClassName.StartWithCapital
 * @phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound
 */
class cnMeta {

	/**
	 * Retrieve metadata for the specified object.
	 *
	 * NOTE: This is the Connections equivalent of @see get_metadata() in WordPress core ../wp-includes/meta.php
	 *
	 * @since 8.1.7
	 *
	 * @param string $type   Type of object metadata is for (e.g., entry, term).
	 * @param int    $id     ID of the object metadata is for.
	 * @param string $key    Optional. Metadata key. If not specified, retrieve all metadata for the specified object.
	 * @param bool   $single Optional, default is FALSE. If true, return only the first value of the
	 *                       specified meta_key. This parameter has no effect if $key is not specified.
	 *
	 * @return bool|string|array Single metadata value, or array of values.
	 */
	public static function get( $type, $id, $key = '', $single = false ) {

		if ( ! $type || ! is_numeric( $id ) ) {

			return false;
		}

		$id = absint( $id );

		if ( ! $id ) {

			return false;
		}

		/**
		 * Filter whether to retrieve metadata of a specific type.
		 *
		 * The dynamic portion of the hook, `$type`, refers to the meta object type (entry, term).
		 * Returning a non-null value will effectively short-circuit the function.
		 *
		 * @since 8.1.7
		 *
		 * @param null|array|string $value     The value should return a single metadata value, or an array of values.
		 * @param int               $id        Object ID.
		 * @param string            $key       Meta key.
		 * @param string|array      $single    Meta value, or an array of values.
		 */
		$check = apply_filters( "cn_get_{$type}_metadata", null, $id, $key, $single );

		if ( null !== $check ) {

			if ( $single && is_array( $check ) ) {

				return $check[0];

			} else {

				return $check;
			}
		}

		$meta_cache = wp_cache_get( $id, 'cn_' . $type . '_meta' );

		if ( ! $meta_cache ) {

			$meta_cache = self::updateCache( $type, array( $id ) );
			$meta_cache = $meta_cache[ $id ];
		}

		if ( ! $key ) {

			return $meta_cache;
		}

		if ( isset( $meta_cache[ $key ] ) ) {

			if ( $single ) {

				return _::maybeJSONdecode( $meta_cache[ $key ][0] );

			} else {

				return array_map( array( 'Connections_Directory\Utility\_', 'maybeJSONdecode' ), $meta_cache[ $key ] );
			}
		}

		if ( $single ) {

			return '';

		} else {

			return array();
		}
	}

	/**
	 * Update the metadata cache for the specified objects.
	 *
	 * NOTE: This is the Connections equivalent of @see update_meta_cache() in WordPress core ../wp-includes/meta.php
	 *
	 * @since 8.1.7
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string    $type       Type of object metadata is for (e.g., entry, term).
	 * @param int|array $object_ids array or comma delimited list of object IDs to update.
	 *
	 * @return array|false Metadata for the specified objects, or FALSE on failure.
	 */
	public static function updateCache( $type, $object_ids ) {

		/** @var wpdb $wpdb */
		global $wpdb;

		if ( ! $type || ! $object_ids ) {
			return false;
		}

		$table  = self::tableName( $type );
		$column = sanitize_key( $type . '_id' );

		if ( ! is_array( $object_ids ) ) {

			$object_ids = preg_replace( '|[^0-9,]|', '', $object_ids );
			$object_ids = explode( ',', $object_ids );
		}

		$object_ids = array_map( 'intval', $object_ids );

		$cache_key = 'cn_' . $type . '_meta';
		$ids       = array();
		$cache     = array();

		foreach ( $object_ids as $id ) {

			$cached_object = wp_cache_get( $id, $cache_key );

			if ( false === $cached_object ) {

				$ids[] = $id;

			} else {

				$cache[ $id ] = $cached_object;
			}
		}

		if ( empty( $ids ) ) {

			return $cache;
		}

		// Get meta data.
		$id_list   = join( ',', $ids );
		$meta_list = $wpdb->get_results(
			"SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY meta_id ASC",
			ARRAY_A
		);

		if ( ! empty( $meta_list ) ) {

			foreach ( $meta_list as $metarow ) {

				$mpid = intval( $metarow[ $column ] );
				$mkey = $metarow['meta_key'];
				$mval = $metarow['meta_value'];

				// Force sub keys to be array type.
				if ( ! isset( $cache[ $mpid ] ) || ! is_array( $cache[ $mpid ] ) ) {

					$cache[ $mpid ] = array();
				}

				if ( ! isset( $cache[ $mpid ][ $mkey ] ) || ! is_array( $cache[ $mpid ][ $mkey ] ) ) {

					$cache[ $mpid ][ $mkey ] = array();
				}

				// Add a value to the current pid/key.
				$cache[ $mpid ][ $mkey ][] = $mval;
			}
		}

		foreach ( $ids as $id ) {

			if ( ! isset( $cache[ $id ] ) ) {

				$cache[ $id ] = array();
			}

			wp_cache_add( $id, $cache[ $id ], $cache_key );
		}

		return $cache;
	}

	/**
	 * Add metadata to the supplied object type id.
	 *
	 * @since 0.8
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $type   The type of object the metadata is for; ie. entry and term.
	 * @param int    $id     The object ID.
	 * @param string $key    Metadata key.
	 * @param string $value  Metadata value.
	 * @param bool   $unique [optional] Whether the specified metadata key should be unique for the object.
	 *                       If TRUE, and the object already has a value for the specified metadata key, no change will be made.
	 *
	 * @return int|false The metadata ID on successful insert or FALSE on failure.
	 */
	public static function add( $type, $id, $key, $value, $unique = false ) {

		/** @var $wpdb wpdb */
		global $wpdb;

		if ( ! $type || ! $key || ! is_numeric( $id ) ) {
			return false;
		}

		$id = absint( $id );
		if ( ! $id ) {
			return false;
		}

		$table  = self::tableName( $type );
		$column = sanitize_key( $type . '_id' );

		$key   = wp_unslash( $key );
		$value = wp_unslash( $value );
		$value = sanitize_meta( $key, $value, 'cn_' . $type );

		/**
		 * Filter whether to add metadata of a specific type.
		 *
		 * The dynamic portion of the hook, `$type`, refers to the meta object type (entry, term).
		 * Returning a non-null value will effectively short-circuit the function.
		 *
		 * @since 8.1.7
		 *
		 * @param null|bool $check  Whether to allow adding metadata for the given type.
		 * @param int       $id     Object ID.
		 * @param string    $key    Meta key.
		 * @param mixed     $value  Meta value. Must be able to be json encoded if non-scalar.
		 *                          Use @see _::maybeJSONencode().
		 * @param bool      $unique Whether the specified meta key should be unique
		 *                          for the object. Optional. Default false.
		 */
		$check = apply_filters( "cn_add_{$type}_metadata", null, $id, $key, $value, $unique );

		if ( null !== $check ) {
			return $check;
		}

		if ( $unique && $wpdb->get_var(
			$wpdb->prepare(
				'SELECT COUNT(*) FROM ' . $table . " WHERE meta_key = %s AND $column = %d",
				$key,
				$id
			)
		)
		) {

			return false;
		}

		/**
		 * Fires immediately before meta of a specific type is added.
		 *
		 * The dynamic portion of the hook, `$type`, refers to the meta object type (entry, term).
		 *
		 * @since 8.1.7
		 *
		 * @param int    $id    Object ID.
		 * @param string $key   Meta key.
		 * @param mixed  $value Meta value.
		 */
		do_action( "cn_add_{$type}_meta", $id, $key, $value );

		// Hard code the entry meta table for now. As other meta tables are added this will have to change based $type.
		$result = $wpdb->insert(
			$table,
			array(
				$column      => $id,
				'meta_key'   => $key,
				'meta_value' => _::maybeJSONencode( $value ),
			)
		);

		if ( ! $result ) {
			return false;
		}

		$metaID = (int) $wpdb->insert_id;

		wp_cache_delete( $id, 'cn_' . $type . '_meta' );

		/**
		 * Fires immediately after meta of a specific type is added.
		 *
		 * The dynamic portion of the hook, `$type`, refers to the meta object type (entry, term).
		 *
		 * @since 8.1.7
		 *
		 * @param int    $metaID The meta ID after successful update.
		 * @param int    $id     Object ID.
		 * @param string $key    Meta key.
		 * @param mixed  $value  Meta value.
		 */
		do_action( "cn_added_{$type}_meta", $metaID, $id, $key, $value );

		return $metaID;
	}

	/**
	 * Update metadata for the specified object. If no value already exists for the specified object
	 * ID and metadata key, the metadata will be added.
	 *
	 * NOTE: This is the Connections equivalent of @see update_metadata() in WordPress core ../wp-includes/meta.php
	 *
	 * @since 8.1.7
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $type       Type of object metadata is for (e.g., entry, term).
	 * @param int    $id         ID of the object metadata is for.
	 * @param string $key        Metadata key.
	 * @param mixed  $value      Metadata value. Must be able to be JSON encoded if non-scalar.
	 *                           Use @see _::maybeJSONencode().
	 * @param mixed  $prev_value Optional. If specified, only update existing metadata entries with
	 *                           the specified value. Otherwise, update all entries.
	 *
	 * @return int|false Meta ID if the key didn't exist, true on successful update, false on failure.
	 */
	public static function update( $type, $id, $key, $value, $prev_value = '' ) {

		/** @var wpdb $wpdb */
		global $wpdb;

		if ( ! $type || ! $key || ! is_numeric( $id ) ) {
			return false;
		}

		$id = absint( $id );
		if ( ! $id ) {
			return false;
		}

		$table  = self::tableName( $type );
		$column = sanitize_key( $type . '_id' );

		// expected_slashed ($meta_key).
		$key          = wp_unslash( $key );
		$passed_value = $value;
		$value        = wp_unslash( $value );
		$value        = sanitize_meta( $key, $value, 'cn_' . $type );

		/**
		 * Filter whether to update metadata of a specific type.
		 *
		 * The dynamic portion of the hook, `$type`, refers to the meta object type (entry, term).
		 * Returning a non-null value will effectively short-circuit the function.
		 *
		 * @since 8.1.7
		 *
		 * @param null|bool $check      Whether to allow updating metadata for the given type.
		 * @param int       $id         Object ID.
		 * @param string    $key        Meta key.
		 * @param mixed     $value      Meta value. Must be able to be JSON encoded if non-scalar.
		 *                              Use @see _::maybeJSONencode().
		 * @param mixed     $prev_value Optional. If specified, only update existing
		 *                              metadata entries with the specified value.
		 *                              Otherwise, update all entries.
		 */
		$check = apply_filters(
			"cn_update_{$type}_metadata",
			null,
			$id,
			$key,
			$value,
			$prev_value
		);
		if ( null !== $check ) {
			return (bool) $check;
		}

		// Compare existing value to new value if no prev value given and the key exists only once.
		if ( empty( $prev_value ) ) {

			$old_value = self::get( $type, $id, $key );

			if ( count( $old_value ) == 1 ) {

				if ( $old_value[0] === $value ) {

					return false;
				}
			}
		}

		$meta_ids = $wpdb->get_col(
			$wpdb->prepare( "SELECT meta_id FROM $table WHERE meta_key = %s AND $column = %d", $key, $id )
		);

		if ( empty( $meta_ids ) ) {

			return self::add( $type, $id, $key, $passed_value );
		}

		$_meta_value = $value;
		$value       = _::maybeJSONencode( $value );

		$data  = array( 'meta_value' => $value );
		$where = array( $column => $id, 'meta_key' => $key );

		if ( ! empty( $prev_value ) ) {

			$prev_value          = _::maybeJSONencode( $prev_value );
			$where['meta_value'] = $prev_value;
		}

		foreach ( $meta_ids as $meta_id ) {
			/**
			 * Fires immediately before updating metadata of a specific type.
			 *
			 * The dynamic portion of the hook, `$type`, refers to the meta object type (entry, term).
			 *
			 * @since 8.1.7
			 *
			 * @param int    $meta_id ID of the metadata entry to update.
			 * @param int    $id      Object ID.
			 * @param string $key     Meta key.
			 * @param mixed  $value   Meta value.
			 */
			do_action( "cn_update_{$type}_meta", $meta_id, $id, $key, $_meta_value );
		}

		$result = $wpdb->update( $table, $data, $where );

		if ( ! $result ) {

			return false;
		}

		wp_cache_delete( $id, 'cn_' . $type . '_meta' );

		foreach ( $meta_ids as $meta_id ) {
			/**
			 * Fires immediately after updating metadata of a specific type.
			 *
			 * The dynamic portion of the hook, `$type`, refers to the meta object type (entry, term).
			 *
			 * @since 8.1.7
			 *
			 * @param int    $meta_id ID of updated metadata entry.
			 * @param int    $id      Object ID.
			 * @param string $key     Meta key.
			 * @param mixed  $value   Meta value.
			 */
			do_action( "cn_updated_{$type}_meta", $meta_id, $id, $key, $_meta_value );
		}

		return true;
	}

	/**
	 * Delete metadata for the specified object.
	 *
	 * NOTE: This is the Connections equivalent of @see delete_metadata() in WordPress core ../wp-includes/meta.php
	 *
	 * @since 8.1.7
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $type       Type of object metadata is for (e.g., entry, term).
	 * @param int    $id         ID of the object metadata is for.
	 * @param string $key        Metadata key.
	 * @param mixed  $value      Optional. Metadata value. Must be able to be JSON encoded if non-scalar. If specified,
	 *                           only delete metadata entries with this value. Otherwise, delete all entries with the
	 *                           specified $key.
	 * @param bool   $delete_all Optional, default is FALSE. If true, delete matching metadata entries
	 *                           for all objects, ignoring the specified $id. Otherwise, only delete matching
	 *                           metadata entries for the specified $id.
	 *
	 * @return bool TRUE on successful delete, FALSE on failure.
	 */
	public static function delete( $type, $id, $key, $value = '', $delete_all = false ) {

		/** @var wpdb $wpdb */
		global $wpdb;

		if ( ! $type || ! $key || ! is_numeric( $id ) && ! $delete_all ) {
			return false;
		}

		$id = absint( $id );
		if ( ! $id && ! $delete_all ) {
			return false;
		}

		$table = self::tableName( $type );

		$type_column = sanitize_key( $type . '_id' );
		$key         = wp_unslash( $key );
		$value       = wp_unslash( $value );

		/**
		 * Filter whether to delete metadata of a specific type.
		 *
		 * The dynamic portion of the hook, `$type`, refers to the meta object type (entry, term).
		 * Returning a non-null value will effectively short-circuit the function.
		 *
		 * @since 8.1.7
		 *
		 * @param null|bool $delete     Whether to allow metadata deletion of the given type.
		 * @param int       $id         Object ID.
		 * @param string    $key        Meta key.
		 * @param mixed     $value      Meta value. Must be able to be JSON encoded if non-scalar.
		 *                              Use @see _::maybeJSONencode().
		 * @param bool $delete_all      Whether to delete the matching metadata entries for all objects,
		 *                              ignoring the specified $id.
		 *                              Default FALSE.
		 */
		$check = apply_filters( "cn_delete_{$type}_metadata", null, $id, $key, $value, $delete_all );
		if ( null !== $check ) {
			return (bool) $check;
		}

		$_meta_value = $value;
		$value       = _::maybeJSONencode( $value );

		$query = $wpdb->prepare( "SELECT meta_id FROM $table WHERE meta_key = %s", $key );

		if ( ! $delete_all ) {
			$query .= $wpdb->prepare( " AND $type_column = %d", $id );
		}

		if ( $value ) {
			$query .= $wpdb->prepare( ' AND meta_value = %s', $value );
		}

		$meta_ids = $wpdb->get_col( $query );
		if ( ! count( $meta_ids ) ) {
			return false;
		}

		if ( $delete_all ) {
			$object_ids = $wpdb->get_col(
				$wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s", $key )
			);
		}

		/**
		 * Fires immediately before deleting metadata of a specific type.
		 *
		 * The dynamic portion of the hook, `$type`, refers to the meta object type (entry, term).
		 *
		 * @since 8.1.7
		 *
		 * @param array  $meta_ids An array of metadata IDs to delete.
		 * @param int    $id       Object ID.
		 * @param string $key      Meta key.
		 * @param mixed  $value    Meta value.
		 */
		do_action( "cn_delete_{$type}_meta", $meta_ids, $id, $key, $_meta_value );

		$query = "DELETE FROM $table WHERE meta_id IN( " . implode( ',', $meta_ids ) . ' )';

		$count = $wpdb->query( $query );

		if ( ! $count ) {
			return false;
		}

		if ( $delete_all && isset( $object_ids ) ) {

			foreach ( (array) $object_ids as $o_id ) {

				wp_cache_delete( $o_id, 'cn_' . $type . '_meta' );
			}

		} else {

			wp_cache_delete( $id, 'cn_' . $type . '_meta' );
		}

		/**
		 * Fires immediately after deleting metadata of a specific type.
		 *
		 * The dynamic portion of the hook name, `$type`, refers to the meta object type (entry, term).
		 *
		 * @since 8.1.7
		 *
		 * @param array  $meta_ids An array of deleted metadata entry IDs.
		 * @param int    $id       Object ID.
		 * @param string $key      Meta key.
		 * @param mixed  $value    Meta value.
		 */
		do_action( "cn_deleted_{$type}_meta", $meta_ids, $id, $key, $_meta_value );

		return true;
	}

	/**
	 * Get meta by ID.
	 *
	 * NOTE: This is the Connections equivalent of @see get_metadata_by_mid() in WordPress core ../wp-includes/meta.php
	 *
	 * @since 8.1.7
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $type Type of object metadata is for (e.g., entry, term).
	 * @param int    $id   ID for a specific meta row.
	 *
	 * @return object|false Meta object or FALSE.
	 */
	public static function getByID( $type, $id ) {

		/** @var wpdb $wpdb */
		global $wpdb;

		if ( ! $type || ! is_numeric( $id ) ) {
			return false;
		}

		$id = absint( $id );
		if ( ! $id ) {
			return false;
		}

		$table = self::tableName( $type );

		$meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE meta_id = %d", $id ) );

		if ( empty( $meta ) ) {
			return false;
		}

		if ( isset( $meta->meta_value ) ) {

			$meta->meta_value = _::maybeJSONdecode( $meta->meta_value );
		}

		return $meta;
	}

	/**
	 * Update meta by ID.
	 *
	 * NOTE: This is the Connections equivalent of @see update_metadata_by_mid() in WordPress core ../wp-includes/meta.php
	 *
	 * @since 8.1.7
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $type  Type of object metadata is for (e.g., entry, term).
	 * @param int    $id    ID for a specific meta row.
	 * @param string $value Metadata value.
	 * @param mixed  $key   string|bool Optional, you can provide a meta key to update it.
	 *
	 * @return bool TRUE on successful update, FALSE on failure.
	 */
	public static function updateByID( $type, $id, $value, $key = false ) {

		/** @var wpdb $wpdb */
		global $wpdb;

		// Make sure everything is valid.
		if ( ! $type || ! is_numeric( $id ) ) {

			return false;
		}

		$id = absint( $id );
		if ( ! $id ) {
			return false;
		}

		$table     = self::tableName( $type );
		$column    = sanitize_key( $type . '_id' );
		$id_column = 'meta_id';

		// Fetch the meta and go on if it's found.
		if ( $meta = self::getByID( $type, $id ) ) {

			$original_key = $meta->meta_key;
			$object_id    = $meta->{$column};

			// If a new meta_key (last parameter) was specified, change the meta key,
			// otherwise use the original key in the update statement.
			if ( false === $key ) {

				$key = $original_key;

			} elseif ( ! is_string( $key ) ) {

				return false;
			}

			// Sanitize the meta.
			$_meta_value = $value;
			$value       = wp_unslash( $value );
			$value       = sanitize_meta( $key, $value, 'cn_' . $type );
			$value       = _::maybeJSONencode( $value );

			// Format the data query arguments.
			$data = array(
				'meta_key'   => $key,
				'meta_value' => $value,
			);

			// Format the where query arguments.
			$where               = array();
			$where[ $id_column ] = $id;

			/** This action is documented in includes/class.meta.php */
			do_action( "cn_update_{$type}_meta", $id, $object_id, $key, $_meta_value );

			// Run the update query, all fields in $data are %s, $where is a %d.
			$result = $wpdb->update( $table, $data, $where, '%s', '%d' );
			if ( ! $result ) {
				return false;
			}

			// Clear the caches.
			wp_cache_delete( $object_id, 'cn_' . $type . '_meta' );

			/** This action is documented in includes/class.meta.php */
			do_action( "cn_updated_{$type}_meta", $id, $object_id, $key, $_meta_value );

			return true;
		}

		// And if the meta was not found.
		return false;
	}

	/**
	 * Delete metadata by meta ID.
	 *
	 * NOTE: This is the Connections equivalent of @see delete_metadata_by_mid() in WordPress core ../wp-includes/meta.php
	 *
	 * @since 8.1.7
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $type Type of object metadata is for (e.g., entry, term).
	 * @param int    $id   ID for a specific meta row.
	 *
	 * @return bool True on successful delete, false on failure.
	 */
	public static function deleteByID( $type, $id ) {

		/** @var wpdb $wpdb */
		global $wpdb;

		// Make sure everything is valid.
		if ( ! $type || ! is_numeric( $id ) ) {
			return false;
		}

		$id = absint( $id );
		if ( ! $id ) {
			return false;
		}

		$table = cnMeta::tableName( $type );

		// object and id columns.
		$column = sanitize_key( $type . '_id' );

		// Fetch the meta and go on if it's found.
		if ( $meta = cnMeta::getByID( $type, $id ) ) {

			$object_id = $meta->{$column};

			/** This action is documented in wp-includes/meta.php */
			do_action( "cn_delete_{$type}_meta", (array) $id, $object_id, $meta->meta_key, $meta->meta_value );

			// Run the query, will return true if deleted, false otherwise.
			$result = (bool) $wpdb->delete( $table, array( 'meta_id' => $id ) );

			// Clear the caches.
			wp_cache_delete( $object_id, 'cn_' . $type . '_meta' );

			/** This action is documented in wp-includes/meta.php */
			do_action( "cn_deleted_{$type}_meta", (array) $id, $object_id, $meta->meta_key, $meta->meta_value );

			return $result;
		}

		return false;
	}

	/**
	 * Retrieve the specified meta keys.
	 *
	 * @since 0.8
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $type  The object type.
	 * @param int    $limit Limit the number of keys to retrieve.
	 *
	 * @return array An array of meta keys.
	 */
	public static function key( $type, $limit = 30 ) {

		/** @var $wpdb wpdb */
		global $wpdb;

		// $column = sanitize_key( $type . '_id' );

		// $keys  = array();
		$limit = (int) apply_filters( "cn_metakey_limit-$type", $limit );

		// Hard code the entry meta table for now. As other meta tables are added this will have to change based $type.
		// The query will not retrieve any meta key that begin with an '_' [underscore].
		$sql = $wpdb->prepare(
			'SELECT meta_key FROM ' . CN_ENTRY_TABLE_META . ' GROUP BY meta_key HAVING meta_key NOT LIKE \'\\_%%\' ORDER BY meta_key LIMIT %d',
			// empty( $key ) ? '' : ' WHERE meta_key IN ("' . implode( '", "', $keys ) . '") ',
			absint( $limit )
		);

		$keys = $wpdb->get_col( $sql );

		if ( $keys ) {
			natcasesort( $keys );
		}

		foreach ( $keys as $i => $key ) {

			if ( self::isPrivate( $key ) ) {
				unset( $keys[ $i ] );
			}
		}

		return $keys;
	}

	/**
	 * Checks whether the `key` is private or not.
	 *
	 * @since 0.8
	 *
	 * @param string $key  The key to check.
	 * @param string $type The object type.
	 *
	 * @return bool
	 */
	public static function isPrivate( $key, $type = null ) {

		$private = false;

		if ( is_string( $key ) && strlen( $key ) > 0 ) {

			$private = ( '_' == $key[0] );

			// Grab the registered metaboxes from the options table.
			// $metaboxes = get_option( 'connections_metaboxes', array() );
			$metaboxes = cnMetaboxAPI::get();

			// Loop thru all fields registered as part of a metabox.
			// If one id found consider it private and exit the loops.
			//
			// NOTE: All fields registered via the metabox  API are considered private.
			// The expectation is an action will be called to render the metadata.
			foreach ( $metaboxes as $metabox ) {

				if ( isset( $metabox['fields'] ) ) {

					foreach ( $metabox['fields'] as $field ) {

						if ( $field['id'] == $key ) {

							// Field found, it's private ... exit loop.
							$private = true;
							continue;
						}
					}
				}

				if ( isset( $metabox['sections'] ) ) {

					foreach ( $metabox['sections'] as $section ) {

						foreach ( $section['fields'] as $field ) {

							if ( $field['id'] == $key ) {

								// Field found, it's private ... exit the loops.
								$private = true;
								continue( 2 );
							}
						}
					}
				}
			}

		}

		return apply_filters( 'cn_is_private_meta', $private, $key, $type );
	}

	/**
	 * Retrieve the name of the metadata table for the specified meta type.
	 *
	 * @since 8.1.7
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $type Type of object to get metadata table name for (e.g., entry, term).
	 *
	 * @return string
	 */
	public static function tableName( $type ) {

		/** @var wpdb $wpdb */
		global $wpdb;

		/*
		 * Set the table prefix accordingly depending if Connections is installed on a multisite WP installation.
		 */
		$prefix = ( is_multisite() && CN_MULTISITE_ENABLED ) ? $wpdb->prefix : $wpdb->base_prefix;

		if ( 'entry' == $type ) {

			$name = CN_ENTRY_TABLE_META;

		} else {

			$name = "{$prefix}connections_{$type}_meta";
		}

		return $name;
	}
}