Skip to content
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
150 changes: 99 additions & 51 deletions includes/class-convertkit-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -625,61 +625,109 @@ public function get_secret_keys() {
*/
public function get_schema() {

return array(
'type' => 'object',
'additionalProperties' => false,
'properties' => array(
'non_inline_form' => array(
'type' => 'array',
'items' => array( 'type' => 'integer' ),
'description' => __( 'IDs of non-inline Forms to display site-wide.', 'convertkit' ),
),
'non_inline_form_honor_none_setting' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether the site-wide non-inline Form honors a per-Page / per-Post "None" Form setting.', 'convertkit' ),
),
'non_inline_form_limit_per_session' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether to limit non-inline Form display to once per session.', 'convertkit' ),
),
'recaptcha_site_key' => array(
'type' => 'string',
'description' => __( 'Google reCAPTCHA v3 site key.', 'convertkit' ),
),
'recaptcha_minimum_score' => array(
'type' => 'number',
'minimum' => 0,
'maximum' => 1,
'description' => __( 'Minimum Google reCAPTCHA v3 score (0.0 - 1.0) below which a request is treated as spam.', 'convertkit' ),
),
'debug' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether debug logging is enabled.', 'convertkit' ),
),
'no_scripts' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether the Plugin\'s frontend JavaScript is disabled.', 'convertkit' ),
$properties = array(
'non_inline_form' => array(
'type' => 'array',
'items' => array( 'type' => 'integer' ),
'description' => __( 'IDs of non-inline Forms to display site-wide.', 'convertkit' ),
),
'non_inline_form_honor_none_setting' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether the site-wide non-inline Form honors a per-Page / per-Post "None" Form setting.', 'convertkit' ),
),
'non_inline_form_limit_per_session' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether to limit non-inline Form display to once per session.', 'convertkit' ),
),
'recaptcha_site_key' => array(
'type' => 'string',
'description' => __( 'Google reCAPTCHA v3 site key.', 'convertkit' ),
),
'recaptcha_minimum_score' => array(
'type' => 'number',
'minimum' => 0,
'maximum' => 1,
'description' => __( 'Minimum Google reCAPTCHA v3 score (0.0 - 1.0) below which a request is treated as spam.', 'convertkit' ),
),
'debug' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether debug logging is enabled.', 'convertkit' ),
),
'no_scripts' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether the Plugin\'s frontend JavaScript is disabled.', 'convertkit' ),
),
'no_css' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether the Plugin\'s frontend CSS is disabled.', 'convertkit' ),
),
'no_add_new_button' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether the "Add New" button for Landing Pages / Member Content is hidden in the WordPress Admin.', 'convertkit' ),
),
'usage_tracking' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether anonymous usage tracking is enabled.', 'convertkit' ),
),
);

// Per-post-type Default Form settings, mirroring get_defaults().
foreach ( convertkit_get_supported_post_types() as $post_type ) {
$properties[ $post_type . '_form' ] = array(
'type' => 'integer',
'minimum' => -1,
'description' => sprintf(
/* translators: Post type slug. */
__( 'Default Form ID to display on %s. `-1` = Plugin Default; `0` = None; positive integer = specific Kit Form ID.', 'convertkit' ),
$post_type
),
'no_css' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether the Plugin\'s frontend CSS is disabled.', 'convertkit' ),
);

$properties[ $post_type . '_form_position' ] = array(
'type' => 'string',
'enum' => array( 'before_content', 'after_content', 'before_after_content', 'after_element' ),
'description' => sprintf(
/* translators: Post type slug. */
__( 'Where the Default Form displays relative to the %s content.', 'convertkit' ),
$post_type
),
'no_add_new_button' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether the "Add New" button for Landing Pages / Member Content is hidden in the WordPress Admin.', 'convertkit' ),
);

$properties[ $post_type . '_form_position_element' ] = array(
'type' => 'string',
'enum' => array( 'p', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ),
'description' => sprintf(
/* translators: 1: Post type slug, 2: Post type slug. */
__( 'HTML element after which to display the Default Form on %1$s. Only used when `%2$s_form_position` is `after_element`.', 'convertkit' ),
$post_type,
$post_type
),
'usage_tracking' => array(
'type' => 'string',
'enum' => array( '', 'on' ),
'description' => __( 'Whether anonymous usage tracking is enabled.', 'convertkit' ),
);

$properties[ $post_type . '_form_position_element_index' ] = array(
'type' => 'integer',
'minimum' => 1,
'maximum' => 999,
'description' => sprintf(
/* translators: 1: Post type slug, 2: Post type slug. */
__( 'Nth occurrence of the element after which to display the Default Form on %1$s. Only used when `%2$s_form_position` is `after_element`.', 'convertkit' ),
$post_type,
$post_type
),
),
);
}

return array(
'type' => 'object',
'additionalProperties' => false,
'properties' => $properties,
);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,18 @@ protected function get_settings_schema_properties() {
),
'landing_page' => array(
'type' => 'string',
'description' => __( 'Kit Landing Page ID to display instead of the Post content. Empty string for none.', 'convertkit' ),
'description' => __( 'Kit Landing Page ID to display instead of the Post content. `0` or empty string for none.', 'convertkit' ),
'pattern' => '^([0-9]+)?$',
),
'tag' => array(
'type' => 'string',
'description' => __( 'Kit Tag ID to apply when the Post is viewed by a Kit subscriber. Empty string for none.', 'convertkit' ),
'description' => __( 'Kit Tag ID to apply when the Post is viewed by a Kit subscriber. `0` or empty string for none.', 'convertkit' ),
'pattern' => '^([0-9]+)?$',
),
'restrict_content' => array(
'type' => 'string',
'description' => __( 'Restrict Post content to Kit subscribers. Empty string for no restriction, or one of `form_<id>`, `tag_<id>`, `product_<id>` to require subscription to that resource.', 'convertkit' ),
'pattern' => '^$|^(form|tag|product)_[1-9][0-9]*$',
'description' => __( 'Restrict Post content to Kit subscribers. Empty string or `0` for no restriction, or one of `form_<id>`, `tag_<id>`, `product_<id>` to require subscription to that resource.', 'convertkit' ),
'pattern' => '^$|^0$|^(form|tag|product)_[1-9][0-9]*$',
),
);

Expand Down
6 changes: 3 additions & 3 deletions tests/Integration/MCPPostSettingsGetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ public function testGetReturnsDefaultsWhenNoMetaExists()
$this->assertIsArray($result);
$this->assertSame($post_id, $result['post_id']);
$this->assertSame('-1', $result['form']);
$this->assertSame('', $result['landing_page']);
$this->assertSame('', $result['tag']);
$this->assertSame('', $result['restrict_content']);
$this->assertSame('0', $result['landing_page']);
$this->assertSame('0', $result['tag']);
$this->assertSame('0', $result['restrict_content']);
}

/**
Expand Down
25 changes: 25 additions & 0 deletions tests/Integration/MCPPostSettingsUpdateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,31 @@ public function testUpdateRejectsInvalidFormValue()
$this->assertInstanceOf(\WP_Error::class, $result);
}

/**
* Test that update accepts `0` for restrict_content as a synonym for
* "no restriction". Matches what ConvertKit_Post::get_default_settings()
* returns and what the metabox / Gutenberg sidebar submit for the "None"
* option, so the get -> update round-trip works for defaulted posts.
*
* @since 3.4.0
*/
public function testUpdateAcceptsZeroForRestrictContent()
{
$post_id = $this->createPostAsAdmin();

$abilities = convertkit_get_abilities();

$result = $abilities[ self::ABILITY_NAME ]->execute_callback(
[
'post_id' => $post_id,
'restrict_content' => '0',
]
);

$this->assertIsArray($result);
$this->assertSame('0', $result['restrict_content']);
}

/**
* Test that update rejects a malformed restrict_content prefix
* (must be form_, tag_ or product_).
Expand Down
Loading
Loading