Skip to content

Commit

Permalink
Declare post type support based on the admin setting and allow overwrite
Browse files Browse the repository at this point in the history
  • Loading branch information
ThierryA committed Nov 24, 2017
1 parent 99e7bcf commit 68c5017
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 33 deletions.
17 changes: 14 additions & 3 deletions amp.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

require_once AMP__DIR__ . '/back-compat/back-compat.php';
require_once AMP__DIR__ . '/includes/amp-helper-functions.php';
require_once AMP__DIR__ . '/includes/amp-post-types-support.php';
require_once AMP__DIR__ . '/includes/admin/functions.php';
require_once AMP__DIR__ . '/includes/admin/class-amp-customizer.php';
require_once AMP__DIR__ . '/includes/settings/class-amp-customizer-settings.php';
Expand Down Expand Up @@ -54,14 +55,11 @@ function amp_init() {
return;
}

define( 'AMP_QUERY_VAR', apply_filters( 'amp_query_var', 'amp' ) );

do_action( 'amp_init' );

load_plugin_textdomain( 'amp', false, plugin_basename( AMP__DIR__ ) . '/languages' );

add_rewrite_endpoint( AMP_QUERY_VAR, EP_PERMALINK );
add_post_type_support( 'post', AMP_QUERY_VAR );

add_filter( 'request', 'amp_force_query_var_value' );
add_action( 'wp', 'amp_maybe_add_actions' );
Expand All @@ -74,6 +72,19 @@ function amp_init() {
}
}

/**
* Define AMP query var.
*
* This function must be invoked through the 'after_setup_theme' action to allow
* the AMP setting to declare the post types support earlier than plugins/theme.
*
* @since 0.6
*/
function define_query_var() {
define( 'AMP_QUERY_VAR', apply_filters( 'amp_query_var', 'amp' ) );
}
add_action( 'after_setup_theme', 'define_query_var', 7 );

// Make sure the `amp` query var has an explicit value.
// Avoids issues when filtering the deprecated `query_string` hook.
function amp_force_query_var_value( $query_vars ) {
Expand Down
7 changes: 2 additions & 5 deletions includes/amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ function amp_get_permalink( $post_id ) {
}

function post_supports_amp( $post ) {
// Listen to post types settings.
$is_enabled_via_setting = (bool) AMP_Settings_Post_Types::get_instance()->get_settings_value( $post->post_type );

// Because `add_rewrite_endpoint` doesn't let us target specific post_types.
if ( ! post_type_supports( $post->post_type, AMP_QUERY_VAR ) && true !== $is_enabled_via_setting ) {
// Because `add_rewrite_endpoint` doesn't let us target specific post_types :(.
if ( ! post_type_supports( $post->post_type, AMP_QUERY_VAR ) ) {
return false;
}

Expand Down
35 changes: 35 additions & 0 deletions includes/amp-post-types-support.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
/**
* AMP Post types support.
*
* @package AMP
* @since 0.6
*/

/**
* Declare core post types support.
*
* @since 0.6
*/
function amp_core_post_types_support() {
add_post_type_support( 'post', AMP_QUERY_VAR );
}
add_action( 'init', 'amp_core_post_types_support' );

/**
* Declare custom post types support.
*
* This function should only be invoked through the 'after_setup_theme' action to
* allow plugins/theme to overwrite the post types support.
*
* @since 0.6
*/
function amp_custom_post_types_support() {
// Listen to post types settings.
foreach ( AMP_Settings_Post_Types::get_instance()->get_settings() as $post_type => $enabled ) {
if ( true === $enabled ) {
add_post_type_support( $post_type, AMP_QUERY_VAR );
}
}
}
add_action( 'after_setup_theme', 'amp_custom_post_types_support' );
96 changes: 85 additions & 11 deletions includes/settings/class-amp-settings-post-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,18 @@ public function __construct() {
public function init() {
add_action( 'admin_init', array( $this, 'register_settings' ) );
add_action( 'update_option_' . AMP_Settings::SETTINGS_KEY, 'flush_rewrite_rules' );
add_action( 'amp_settings_screen', array( $this, 'errors' ) );
}

/**
* Register the current page settings.
*/
public function register_settings() {
register_setting( AMP_Settings::SETTINGS_KEY, AMP_Settings::SETTINGS_KEY );
register_setting(
AMP_Settings::SETTINGS_KEY,
AMP_Settings::SETTINGS_KEY,
array( $this, 'validate' )
);
add_settings_section(
$this->section_id,
false,
Expand All @@ -57,7 +62,7 @@ public function register_settings() {
add_settings_field(
$this->setting['id'],
$this->setting['label'],
array( $this, 'render_setting' ),
array( $this, 'render' ),
AMP_Settings::MENU_SLUG,
$this->section_id
);
Expand All @@ -67,16 +72,24 @@ public function register_settings() {
* Getter for settings value.
*
* @param string $post_type The post type name.
* @return bool Return the setting value.
* @return bool|array Return true if the post type is always on; the setting value otherwise.
*/
public function get_settings_value( $post_type ) {
$settings = get_option( AMP_Settings::SETTINGS_KEY, array() );
public function get_settings( $post_type = false ) {
$settings = $this->validate( get_option( AMP_Settings::SETTINGS_KEY, array() ) );

if ( false !== $post_type ) {
if ( isset( $settings[ $this->setting['id'] ][ $post_type ] ) ) {
return $settings[ $this->setting['id'] ][ $post_type ];
}

if ( isset( $settings[ $this->setting['id'] ][ $post_type ] ) ) {
return (bool) $settings[ $this->setting['id'] ][ $post_type ];
return false;
}

return false;
if ( empty( $settings[ $this->setting['id'] ] ) || ! is_array( $settings[ $this->setting['id'] ] ) ) {
return array();
}

return $settings[ $this->setting['id'] ];
}

/**
Expand All @@ -102,16 +115,77 @@ public function get_supported_post_types() {
* @param string $post_type The post type name.
* @return object The setting HTML input name attribute.
*/
public function get_setting_name( $post_type ) {
public function get_name_attribute( $post_type ) {
$id = $this->setting['id'];

return AMP_Settings::SETTINGS_KEY . "[{$id}][{$post_type}]";
}

/**
* Check whether the post type should be disabled or not.
*
* Since we can't flag a post type which is not enabled by setting and removed by plugin/theme,
* we can't disable the checkbox but the errors() takes care of this scenario.
*
* @param string $post_type The post type name.
* @return bool True if disabled; false otherwise.
*/
public function disabled( $post_type ) {
$settings = $this->get_settings();

// Disable if post type support was not added by setting and added by plugin/theme.
if ( post_type_supports( $post_type, AMP_QUERY_VAR ) && ! isset( $settings[ $post_type ] ) ) {
return true;
}

return false;
}

/**
* Handle errors.
*/
public function errors() {
$settings = $this->get_settings();

foreach ( $settings as $post_type => $value ) {
// Throw error if post type support was added by setting and removed by plugin/theme.
if ( true === $value && ! post_type_supports( $post_type, AMP_QUERY_VAR ) ) {
$post_type_object = get_post_type_object( $post_type );

add_settings_error(
$post_type,
$post_type,
sprintf(
/* Translators: %s: Post type name. */
__( '"%s" could not be activated because support was removed by a plugin or theme', 'amp' ),
isset( $post_type_object->label ) ? $post_type_object->label : $post_type
)
);
}
}
}

/**
* Validate and sanitize the settings.
*
* @param array $settings The post types settings.
* @return array The post types settings.
*/
public function validate( $settings ) {
if ( ! isset( $settings[ $this->setting['id'] ] ) || ! is_array( $settings[ $this->setting['id'] ] ) ) {
return array();
}

foreach ( $settings[ $this->setting['id'] ] as $key => $value ) {
$settings[ $this->setting['id'] ][ $key ] = (bool) $value;
}

return $settings;
}

/**
* Setting renderer.
*/
public function render_setting() {
public function render() {
require_once AMP__DIR__ . '/templates/admin/settings/fields/checkbox-post-types.php';
}

Expand Down
6 changes: 6 additions & 0 deletions includes/settings/class-amp-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ public function render_screen() {
return;
}

/**
* Fires before the AMP settings screen is rendered.
*
* @since 0.6
*/
do_action( 'amp_settings_screen' );
include_once AMP__DIR__ . '/templates/admin/settings/screen.php';
}

Expand Down
2 changes: 1 addition & 1 deletion templates/admin/settings/fields/checkbox-post-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<fieldset>
<?php foreach ( $this->get_supported_post_types() as $post_type ) : ?>
<label>
<input type="checkbox" value="1" name="<?php echo esc_attr( $this->get_setting_name( $post_type->name ) ); ?>"<?php checked( true, (bool) $this->get_settings_value( $post_type->name ) || post_type_supports( $post_type->name, AMP_QUERY_VAR ) ); ?><?php disabled( true, post_type_supports( $post_type->name, AMP_QUERY_VAR ) ); ?>> <?php echo esc_html( $post_type->label ); ?>
<input type="checkbox" value="1" name="<?php echo esc_attr( $this->get_name_attribute( $post_type->name ) ); ?>"<?php checked( true, post_type_supports( $post_type->name, AMP_QUERY_VAR ) ); ?><?php disabled( true, $this->disabled( $post_type->name ) ); ?>> <?php echo esc_html( $post_type->label ); ?>
</label>
<br>
<?php endforeach; ?>
Expand Down
45 changes: 45 additions & 0 deletions tests/test-amp-post-types-support.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Tests for Post Types Support.
*
* @package AMP
* @since 0.6
*/

/**
* Tests for Post Types Support.
*/
class Test_AMP_Post_Types_Support extends WP_UnitTestCase {

/**
* Test amp_core_post_types_support.
*
* @see amp_core_post_types_support()
*/
public function test_init() {
amp_core_post_types_support();
$this->assertTrue( post_type_supports( 'post', AMP_QUERY_VAR ) );
remove_post_type_support( 'post', AMP_QUERY_VAR );
}

/**
* Test amp_custom_post_types_support.
*
* @see amp_custom_post_types_support()
*/
public function test_amp_custom_post_types_support() {
update_option( AMP_Settings::SETTINGS_KEY, array(
'post_types_support' => array(
'foo' => true,
'bar' => true,
),
) );
amp_custom_post_types_support();
$this->assertTrue( post_type_supports( 'foo', AMP_QUERY_VAR ) );
$this->assertTrue( post_type_supports( 'bar', AMP_QUERY_VAR ) );
delete_option( AMP_Settings::SETTINGS_KEY );
remove_post_type_support( 'foo', AMP_QUERY_VAR );
remove_post_type_support( 'bar', AMP_QUERY_VAR );
}

}
Loading

0 comments on commit 68c5017

Please sign in to comment.