Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Settings UI #66

Merged
merged 13 commits into from
Apr 7, 2023
5 changes: 2 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ jobs:
with:
php-version: '7.4'
coverage: none
tools: phpcs
- name: composer install
run: composer install
- name: PHPCS check
uses: chekalsky/phpcs-action@v1
with:
phpcs_bin_path: './vendor/bin/phpcs .'
run: './vendor/bin/phpcs .'
2 changes: 2 additions & 0 deletions config.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
convert_to_blocks_define( 'CONVERT_TO_BLOCKS_VERSION', $plugin_version );
convert_to_blocks_define( 'CONVERT_TO_BLOCKS_DIR', plugin_dir_path( __FILE__ ) );
convert_to_blocks_define( 'CONVERT_TO_BLOCKS_URL', plugin_dir_url( __FILE__ ) );
convert_to_blocks_define( 'CONVERT_TO_BLOCKS_SLUG', 'convert-to-blocks' );
convert_to_blocks_define( 'CONVERT_TO_BLOCKS_DEFAULT_POST_TYPES', [ 'post', 'page' ] );

/* Labels */

Expand Down
25 changes: 21 additions & 4 deletions includes/ConvertToBlocks/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public function init() {
$this->register_objects(
[
new RESTSupport(),
new Settings(),
]
);
}
Expand Down Expand Up @@ -184,14 +185,30 @@ public function init_locale() {
* @return bool
*/
public function post_type_supports_convert_to_blocks( $post_type ) {
$supports = post_type_supports( $post_type, 'convert-to-blocks' );
$use_defaults = apply_filters( 'convert_to_blocks_defaults', true );
$default_post_types = $this->get_default_post_types();
$supports = post_type_supports( $post_type, 'convert-to-blocks' );
$use_defaults = apply_filters( 'convert_to_blocks_defaults', true );
$default_post_types = $this->get_default_post_types();
$user_selected_post_types = get_option( sprintf( '%s_post_types', CONVERT_TO_BLOCKS_SLUG ), $default_post_types );

if ( ! $supports && $use_defaults && in_array( $post_type, $default_post_types, true ) ) {
$supports = true;
}

// For user-selected option via the Settings UI.
if ( false !== $user_selected_post_types ) {
$supports = false;

// If no post_type is selected.
if ( empty( $user_selected_post_types ) ) {
$supports = false;
}

// Check if post_type is selected by the user.
if ( in_array( $post_type, $user_selected_post_types, true ) ) {
$supports = true;
}
}

$supports = apply_filters( 'post_type_supports_convert_to_blocks', $supports, $post_type );

return $supports;
Expand Down Expand Up @@ -257,7 +274,7 @@ public function is_classic_editor_post( $post_id ) {
* @return array
*/
public function get_default_post_types() {
return apply_filters( 'convert_to_blocks_default_post_types', [ 'post', 'page' ] );
return apply_filters( 'convert_to_blocks_default_post_types', CONVERT_TO_BLOCKS_DEFAULT_POST_TYPES );
}

/**
Expand Down
267 changes: 267 additions & 0 deletions includes/ConvertToBlocks/Settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
<?php
/**
* Settings UI
*
* @package convert-to-blocks
*/

namespace ConvertToBlocks;

/**
* UI for configuring plugin settings.
*/
class Settings {

/**
* User permissions to manage settings.
*
* @var string
*/
private $capability = 'manage_options';

/**
* Settings page slug.
*
* @var string
*/
private $settings_page = 'settings-page';

/**
* Settings section name.
*
* @var string
*/
private $settings_section = 'settings-section';

/**
* Settings group name.
*
* @var string
*/
private $settings_group = 'settings';

/**
* Post types.
*
* @var array
*/
private $post_types = [];

/**
* Register hooks with WordPress
*/
public function register() {
// Configure variables and get post types.
$this->init();

add_action( 'admin_menu', [ $this, 'add_menu' ] );
add_action( 'admin_init', [ $this, 'register_section' ], 10 );
add_action( 'admin_init', [ $this, 'register_fields' ], 20 );
add_action( 'admin_notices', [ $this, 'filter_notice' ], 10 );
}

/**
* Only registers on admin context.
*/
public function can_register() {
return is_admin();
}

/**
* Configures variables and fetches post types.
*
* @return void
*/
public function init() {
// Configure variables.
$this->settings_page = sprintf( '%s-%s', CONVERT_TO_BLOCKS_SLUG, $this->settings_page );
$this->settings_section = sprintf( '%s-%s', CONVERT_TO_BLOCKS_SLUG, $this->settings_section );
$this->settings_group = sprintf( '%s_%s', CONVERT_TO_BLOCKS_SLUG, $this->settings_group );

// Get post types.
$this->post_types = $this->get_post_types();
}

/**
* Retrieves all public post types.
*
* @return array
*/
public function get_post_types() {
$post_types = get_post_types(
[ 'public' => true ]
);

if ( ! empty( $post_types['attachment'] ) ) {
unset( $post_types['attachment'] );
}

return $post_types;
}

/**
* Adds a submenu item for the `Settings` menu.
*
* @return void
*/
public function add_menu() {
add_options_page(
esc_html__( 'Convert to Blocks', 'convert-to-blocks' ),
esc_html__( 'Convert to Blocks', 'convert-to-blocks' ),
$this->capability,
CONVERT_TO_BLOCKS_SLUG,
[ $this, 'settings_page' ]
);
}

/**
* Registers the settings page.
*
* @return void
*/
public function settings_page() {
?>
<div class="wrap">
<h1>
<?php esc_html_e( 'Convert to Blocks', 'convert-to-blocks' ); ?>
</h1>
<hr>

<p>
<?php esc_html_e( 'Configure plugin by selecting the supported post types.', 'convert-to-blocks' ); ?>
</p>

<form method="post" action="options.php">
<?php
settings_fields( $this->settings_group );
do_settings_sections( CONVERT_TO_BLOCKS_SLUG );
submit_button();
?>
</form>
</div>
<?php
}

/**
* Registers section for the settings page.
*
* @return void
*/
public function register_section() {
add_settings_section(
$this->settings_section,
false,
false,
CONVERT_TO_BLOCKS_SLUG
);
}

/**
* Registers setting fields.
*
* @return void
*/
public function register_fields() {
// Supported post types.
add_settings_field(
sprintf( '%s_post_types', CONVERT_TO_BLOCKS_SLUG ),
esc_html__( 'Supported Post Types', 'convert-to-blocks' ),
[ $this, 'field_post_types' ],
CONVERT_TO_BLOCKS_SLUG,
$this->settings_section,
[
'label_for' => sprintf( '%s_post_types', CONVERT_TO_BLOCKS_SLUG ),
]
);

register_setting(
$this->settings_group,
sprintf( '%s_post_types', CONVERT_TO_BLOCKS_SLUG ),
[
'sanitize_callback' => [ $this, 'sanitize_post_types' ],
]
);
}

/**
* Renders the `post_types` field.
*
* @return void
*/
public function field_post_types() {
$post_types = get_option(
sprintf( '%s_post_types', CONVERT_TO_BLOCKS_SLUG ),
Plugin::get_instance()->get_default_post_types()
);
$output_html = '';

foreach ( $this->post_types as $post_type ) {
$output_html .= sprintf(
'<label for="%1$s"><input name="%2$s[]" type="checkbox" %3$s id="%1$s" value="%4$s"> %5$s</label> <br>',
sprintf( '%s_post_types_%s', esc_attr( CONVERT_TO_BLOCKS_SLUG ), esc_attr( $post_type ) ),
sprintf( '%s_post_types', esc_attr( CONVERT_TO_BLOCKS_SLUG ) ),
checked( in_array( $post_type, $post_types, true ), 1, false ),
esc_attr( $post_type ),
esc_attr( ucfirst( $post_type ) )
);
}
?>
<fieldset>
<?php echo $output_html; // phpcs:ignore ?>
</fieldset>
<?php
}

/**
* Sanitizes post_types values.
*
* @param array $input Array containing checked values.
*
* @return array Sanitized array.
*/
public function sanitize_post_types( $input ) {
if ( ! is_array( $input ) ) {
return [];
}

return array_map( 'sanitize_text_field', $input );
}

/**
* Adds an admin notice if a filter is active for `post_type_supports_convert_to_blocks` as
* this might overwrite the outcome of the settings stored in DB.
*/
public function filter_notice() {
if ( ! has_filter( 'post_type_supports_convert_to_blocks' ) ) {
return;
}

$show_on_pages = array(
'settings_page_convert-to-blocks',
'plugins',
);

$screen = get_current_screen();

if ( is_null( $screen ) ) {
return;
}

if ( ! ( ! empty( $screen->post_type ) || in_array( $screen->id, $show_on_pages, true ) ) ) {
return;
}

?>
<div class="notice notice-success is-dismissible">
<p>
<?php
printf(
esc_html__( 'A filter hook (post_type_supports_convert_to_blocks) is already active.', 'convert-to-blocks' ),
);
?>
</p>
</div>
<?php
}

}