Skip to content
Open
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
18 changes: 13 additions & 5 deletions includes/class-splash-wordpress-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,18 @@ private function settings_fields()
array(
'id' => 'cf_product',
'label' => __('Custom Fields', 'splash-wordpress-plugin'),
'description' => sprintf(__('Enable Custom Fields for Products. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::MAX_FIELDS),
'description' => sprintf(__('Enable Custom Fields for Products. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::getLimit()),
'type' => 'checkbox',
'default' => '1'
),
array(
'id' => 'custom_fields_limit',
'label' => __('Custom Fields Limit', 'splash-wordpress-plugin'),
'description' => sprintf(__('Maximum number of custom fields exposed per object type. Raise it if your site defines many custom fields (ACF & similar). Default: %d.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::MAX_FIELDS),
'type' => 'number',
'default' => \Splash\Local\Dictionary\CustomFields::MAX_FIELDS,
'placeholder' => (string) \Splash\Local\Dictionary\CustomFields::MAX_FIELDS
),
)
);
$settings['orders'] = array(
Expand All @@ -486,13 +494,13 @@ private function settings_fields()
), array(
'id' => 'cf_order',
'label' => __('Orders Custom Fields', 'splash-wordpress-plugin'),
'description' => sprintf(__('Enable Custom Fields for Orders. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::MAX_FIELDS),
'description' => sprintf(__('Enable Custom Fields for Orders. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::getLimit()),
'type' => 'checkbox',
'default' => '0'
), array(
'id' => 'cf_invoice',
'label' => __('Invoices Custom Fields', 'splash-wordpress-plugin'),
'description' => sprintf(__('Enable Custom Fields for Invoices. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::MAX_FIELDS),
'description' => sprintf(__('Enable Custom Fields for Invoices. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::getLimit()),
'type' => 'checkbox',
'default' => '0'
), array(
Expand Down Expand Up @@ -532,13 +540,13 @@ private function settings_fields()
array(
'id' => 'cf_post',
'label' => __('Posts Custom Fields', 'splash-wordpress-plugin'),
'description' => sprintf(__('Enable Custom Fields for Posts. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::MAX_FIELDS),
'description' => sprintf(__('Enable Custom Fields for Posts. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::getLimit()),
'type' => 'checkbox',
'default' => '0'
), array(
'id' => 'cf_page',
'label' => __('Pages Custom Fields', 'splash-wordpress-plugin'),
'description' => sprintf(__('Enable Custom Fields for Pages. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::MAX_FIELDS),
'description' => sprintf(__('Enable Custom Fields for Pages. Limited to the first %d custom fields.', 'splash-wordpress-plugin'), \Splash\Local\Dictionary\CustomFields::getLimit()),
'type' => 'checkbox',
'default' => '0'
),
Expand Down
19 changes: 18 additions & 1 deletion src/Dictionary/CustomFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,24 @@
class CustomFields
{
/**
* Maximum Number of Custom Fields Exposed per Object Type
* Default Maximum Number of Custom Fields Exposed per Object Type
*/
public const MAX_FIELDS = 200;

/**
* Get Maximum Number of Custom Fields Exposed per Object Type
*
* Sites with many custom fields (ACF & similar) can raise the limit from
* the plugin settings page (Custom Fields Limit) or via the
* splash_custom_fields_limit filter. Defaults to MAX_FIELDS.
*
* @return int
*/
public static function getLimit(): int
{
$limit = (int) get_option('splash_custom_fields_limit', self::MAX_FIELDS);
$limit = (int) apply_filters('splash_custom_fields_limit', ($limit > 0) ? $limit : self::MAX_FIELDS);

return ($limit > 0) ? $limit : self::MAX_FIELDS;
}
}
51 changes: 45 additions & 6 deletions src/Objects/Post/CustomTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,10 @@ protected function buildCustomFields(): void
if (!get_option("splash_cf_".$shortClass)) {
return;
}
//====================================================================//
// Require Posts Functions
require_once(ABSPATH."wp-admin/includes/post.php");

//====================================================================//
// Load List of Custom Fields
/** @var string[] $metaKeys */
$metaKeys = get_meta_keys();
$metaKeys = $this->getObjectMetaKeys();

//====================================================================//
// Filter List of Custom Fields
Expand All @@ -69,7 +65,7 @@ protected function buildCustomFields(): void
}
//====================================================================//
// Limit max Number of Custom Fields
if (\Splash\Local\Dictionary\CustomFields::MAX_FIELDS <= count($metaKeys)) {
if (\Splash\Local\Dictionary\CustomFields::getLimit() <= count($metaKeys)) {
unset($metaKeys[ $index ]);
}
}
Expand All @@ -93,6 +89,49 @@ protected function buildCustomFields(): void
}
}

/**
* Get Distinct Meta Keys used by this Object's Post Type
*
* WordPress core get_meta_keys() scans the whole postmeta table, so every
* object type was offered every meta of the site: order metas showed up as
* Product custom fields, and metas with invalid identifiers triggered
* schema warnings on unrelated objects. Restrict discovery to the metas
* actually attached to this object's post type ("product" also includes
* its variations). Objects without a known post type keep the legacy
* site-wide behaviour.
*
* @return string[]
*/
private function getObjectMetaKeys(): array
{
global $wpdb;

$postType = isset($this->postType) ? (string) $this->postType : "";
if ("" === $postType) {
//====================================================================//
// Legacy Mode => Site Wide Discovery
require_once(ABSPATH."wp-admin/includes/post.php");

/** @var string[] $metaKeys */
$metaKeys = get_meta_keys();

return $metaKeys;
}
$postTypes = array($postType);
if ("product" === $postType) {
$postTypes[] = "product_variation";
}
/** @var string[] $metaKeys */
$metaKeys = $wpdb->get_col(sprintf(
"SELECT DISTINCT pm.meta_key FROM %s pm JOIN %s p ON p.ID = pm.post_id WHERE p.post_type IN ('%s') ORDER BY pm.meta_key",
$wpdb->postmeta,
$wpdb->posts,
implode("','", array_map("esc_sql", $postTypes))
));

return $metaKeys;
}

//====================================================================//
// Fields Reading Functions
//====================================================================//
Expand Down