diff --git a/inc/admin/class-ramp-for-gutenberg-post-type-settings-ui.php b/inc/admin/class-ramp-for-gutenberg-post-type-settings-ui.php index 36f47af..c34e160 100644 --- a/inc/admin/class-ramp-for-gutenberg-post-type-settings-ui.php +++ b/inc/admin/class-ramp-for-gutenberg-post-type-settings-ui.php @@ -52,7 +52,7 @@ public function add_writing_settings_section() { public function sanitize_post_types_callback( $post_types ) { $post_types = array_unique( (array) $post_types ); - $supported_post_types = array_keys( $this->get_supported_post_types() ); + $supported_post_types = array_keys( $this->ramp_for_gutenberg->get_supported_post_types() ); /** * Validate & Sanitize @@ -87,7 +87,7 @@ public function sanitize_post_types_callback( $post_types ) { */ function render_settings_section() { - $post_types = $this->get_supported_post_types(); + $post_types = $this->ramp_for_gutenberg->get_supported_post_types(); $helper_enabled_post_types = (array) $this->ramp_for_gutenberg->get_criteria( 'post_types' ); $enabled_post_types = $this->ramp_for_gutenberg->get_enabled_post_types(); ?> @@ -152,45 +152,5 @@ function render_settings_section() { 'label' ] - */ - public function get_supported_post_types() { - - if ( 0 === did_action( 'init' ) && ! doing_action( 'init' ) ) { - trigger_error( "get_supported_post_types() was called before the init hook. Some post types might not be registered yet.", E_USER_WARNING ); - } - - $post_types = get_post_types( - [ - 'show_ui' => true, - 'show_in_rest' => true, - ], - 'object' - ); - - $available_post_types = array(); - - // Remove post types that don't want an editor - foreach ( $post_types as $name => $post_type_object ) { - if ( post_type_supports( $name, 'editor' ) && ! empty( $post_type_object->label ) ) { - $available_post_types[ $name ] = $post_type_object->label; - } - } - - return $available_post_types; - } } \ No newline at end of file diff --git a/inc/class-ramp-for-gutenberg.php b/inc/class-ramp-for-gutenberg.php index e653ea7..aba6be7 100644 --- a/inc/class-ramp-for-gutenberg.php +++ b/inc/class-ramp-for-gutenberg.php @@ -3,10 +3,19 @@ class Ramp_For_Gutenberg { private static $instance; + + /** + * Criteria is temporarily stored on class instance before it can be validated and updated + * Do not trust raw data stored in $criteria! + * @var mixed null|array + */ + private static $criteria = null; + private $option_name = 'ramp_for_gutenberg_load_critera'; public $active = false; public $load_gutenberg = null; + public static function get_instance() { if ( ! self::$instance ) { self::$instance = new Ramp_For_Gutenberg(); @@ -16,6 +25,14 @@ public static function get_instance() { private function __construct() { $this->option_name = apply_filters( 'ramp_for_gutenberg_option_name', $this->option_name ); + + /** + * Store the criteria on admin_init + * + * $priority = 5 to ensure that the UI class has fresh data available + * To do that, we need this to run before `ramp_for_gutenberg_initialize_admin_ui()` + */ + add_action( 'admin_init', [ $this, 'save_criteria' ], 5, 0 ); } public function get_option_name() { @@ -24,8 +41,8 @@ public function get_option_name() { /** * Get the desired criteria - * @param string $criteria_name - post_types, post_ids, load * + * @param string $criteria_name - post_types, post_ids, load * @return mixed */ public function get_criteria( $criteria_name = '' ) { @@ -44,15 +61,77 @@ public function get_criteria( $criteria_name = '' ) { } - public function save_criteria( $criteria ) { - if ( $this->validate_criteria( $criteria ) ) { - return update_option( $this->get_option_name(), $criteria ); + /** + * Set the private class variable $criteria + * self::$criteria going to be used to update the option when `$this->save_criteria()` is run + * + * @param $criteria + * @return bool + */ + public function set_criteria( $criteria ) { + + if ( $this->sanitize_criteria( $criteria ) ) { + self::$criteria = $criteria; + return true; } + return false; } + /** + * Save criteria in WordPres options if it's valid + */ + public function save_criteria() { + + + if ( null !== self::$criteria && $this->validate_criteria( self::$criteria ) ) { + update_option( $this->get_option_name(), self::$criteria ); + } + + } + + /** + * Make sure that the passed $post_types exist and can support Gutenberg + * + * @param array $post_types + * @return bool + */ + public function validate_post_types( $post_types ) { + + $supported_post_types = array_keys( $this->get_supported_post_types() ); + foreach ( (array) $post_types as $post_type ) { + if ( ! in_array( $post_type, $supported_post_types, true ) ) { + _doing_it_wrong( 'ramp_for_gutenberg_load_gutenberg', "Cannot enable Gutenberg support for post type \"{$post_type}\"", null ); + return false; + } + } + + return true; + } + + /** + * Validate $criteria + * + * @param $criteria + * @return bool + */ public function validate_criteria( $criteria ) { + if ( ! empty( $criteria['post_types'] ) && ! $this->validate_post_types( $criteria['post_types'] ) ) { + return false; + } + + return true; + } + + /** + * Sanitize $criteria by making sure it's formatted properly + * + * @param $criteria + * @return bool + */ + public function sanitize_criteria( $criteria ) { + if ( ! is_array( $criteria ) || ! $criteria ) { return false; } @@ -155,6 +234,46 @@ public function gutenberg_should_load() { } } + /** + * Get post types that can be supported by Gutenberg. + * + * This will get all registered post types and remove post types: + * * that aren't shown in the admin menu + * * like attachment, revision, etc. + * * that don't support native editor UI + * + * + * Also removes post types that don't support `show_in_rest`: + * @link https://github.com/WordPress/gutenberg/issues/3066 + * + * @return array of formatted post types as [ 'slug' => 'label' ] + */ + public function get_supported_post_types() { + + if ( 0 === did_action( 'init' ) && ! doing_action( 'init' ) ) { + _doing_it_wrong( 'Ramp_For_Gutenberg::get_supported_post_types', "get_supported_post_types() was called before the init hook. Some post types might not be registered yet.", '1.0.0' ); + } + + $post_types = get_post_types( + [ + 'show_ui' => true, + 'show_in_rest' => true, + ], + 'object' + ); + + $available_post_types = array(); + + // Remove post types that don't want an editor + foreach ( $post_types as $name => $post_type_object ) { + if ( post_type_supports( $name, 'editor' ) && ! empty( $post_type_object->label ) ) { + $available_post_types[ $name ] = $post_type_object->label; + } + } + + return $available_post_types; + } + /** * Get all post types with Gutenberg enabled * diff --git a/ramp-for-gutenberg.php b/ramp-for-gutenberg.php index 0674765..0b34cdc 100644 --- a/ramp-for-gutenberg.php +++ b/ramp-for-gutenberg.php @@ -43,7 +43,7 @@ function ramp_for_gutenberg_load_gutenberg( $criteria = false ) { $stored_criteria = $RFG->get_criteria(); if ( $criteria !== $stored_criteria ) { // the criteria specified in code have changed -- update them - $criteria = $RFG->save_criteria( $criteria ); + $criteria = $RFG->set_criteria( $criteria ); } // indicate that we've loaded the plugin. $RFG->active = true;