pinkcrab/registerables

Abstract classes for creating post types, taxonomies, metaboxes and ajax calls.

2.0.2 2023-12-16 02:32 UTC

README

logo

Registerables

Latest Stable Version Total Downloads License PHP Version Require GitHub contributors GitHub issues

WP5.9 [PHP7.4-8.1] Tests WP6.0 [PHP7.4-8.1] Tests WP6.1 [PHP7.4-8.2] Tests WP6.2 [PHP7.4-8.2] Tests WP6.3 [PHP7.4-8.2] Tests WP6.4 [PHP7.4-8.2] Tests

codecov Scrutinizer Code Quality Maintainability

A collection of Abstract Classes for creating common WordPress fixtures which need registering.

For Perique V2.0.*

Why?

WordPress has a number of Registerable functions for Post Types, Post Meta and Taxonomies. These tend to require large arrays of arguments to be defined. This library provides Classes which can be registered and used with the Registration process.

Setup

$ composer require pinkcrab/registerables

You need to include the module and the Registerable_Middleware will be included automatically. They come with their own dependencies which will need to be added using the module() method from the App_Factory instance.

$app = ( new PinkCrab\Perique\Application\App_Factory() )
  // Normal Perique bootstrapping.   
  ->module( Registerable::class );
  ->boot();

Once the middleware has been included, you can use Post_Type, Taxonomies, Meta Data and Meta boxes as part of the usual Registration process

Post Type

Creates a simple post type.

use PinkCrab\Registerables\Post_Type;

class Basic_CPT extends Post_Type {

  public string $key      = 'basic_cpt';
  public string $singular = 'Basic';
  public string $plural   = 'Basics';
}

See full Post Type docs

Taxonomy

Creates a flat taxonomy for the Post Post Type.

use PinkCrab\Registerables\Taxonomy;

class Basic_Tag_Taxonomy extends Taxonomy {
  public string $slug         = 'basic_tag_tax';
  public string $singular     = 'Basic Tag Taxonomy';
  public string $plural       = 'Basic Tag Taxonomies';
  public ?string $description  = 'The Basic Tag Taxonomy.';
  public string $hierarchical = false;
  public array $object_type = array( 'post' );
}

See full Taxonomy Docs

Meta Box

Create a simple meta box as part of a post type definition.

class My_CPT extends Post_Type {
  public string $key      = 'my_cpt';
  public string $singular = 'CPT Post';
  public string $plural   = 'CPT Posts';

  public function meta_boxes( array $meta_boxes ): array {
    $meta_boxes = MetaBox::side('my_meta_box')
      ->label('My Meta Box')
      ->view_template($template_path)
      ->view_vars($additional_view_data)
      ->action('save_post', [$this, 'save_method'])
      ->action('update_post', [$this, 'save_method'])
  }
}

If your meta box has any level of complexity, it is recommended to create a separate service which handles this and inject it into the Post_Type class.

/** The Meta Box Service */
class Meta_Box_Service {
  public function get_meta_boxes(): array {
    $meta_boxes = array();
    $meta_boxes[] = MetaBox::side('my_meta_box')
      ->label('My Meta Box')
      ->view_template($template_path)
      ->view_vars($additional_view_data)
      ->action('save_post', [$this, 'save_method'])
      ->action('update_post', [$this, 'save_method'])
  }

  public function save_method( int $post_id ): array {
    // Handle validating and updating post meta.
  }
}

/** Injected into post type */
class My_CPT extends Post_Type {
  public string $key      = 'my_cpt';
  public string $singular = 'CPT Post';
  public string $plural   = 'CPT Posts';

  // Pass the service in as a dependency.
  private Meta_Box_Service $meta_box_service;
  
  public function __construct(Meta_Box_Service $meta_box_service){
    $this->meta_box_service = $meta_box_service;
  }

  // Return the populated Meta_Box instances.
  public function meta_boxes( array $meta_boxes ): array {
    return $this->meta_box_service->get_meta_boxes();
  }
}

See full Meta Box Docs

Shared Meta Boxes

In case you would like to render the same meta box on multiple Custom Post Types or to add it to existing ones, you can use the Shared_Meta_Box_Controller base class and extend it to register independent meta boxes.

class Acme_Meta_Box extends Shared_Meta_Box_Controller {
  /**
   * Return the Meta Box instance.
   */
  public function meta_box(): Meta_Box {
    return Meta_Box::side('acme_box')
      ->label('Acme Meta Box')
      ->screen('acme_post_type_a')
      ->screen('acme_post_type_b')
      ->view_template($template_path)
      ->view_vars($additional_view_data)
      ->action('save_post', [$this, 'save_method'])
      ->action('update_post', [$this, 'save_method'])
  }

  /**
   * Sets any metadata against the meta box.
   * @see Post Type docs for more details
   */
  public function meta_data( array $meta_data ): array {
    $meta_data[] = ( new Meta_Data( 'acme_meta_1' ) )
      ->type( 'integer' )
        ->single......
 
    return $meta_data;
  }

  /** The save_post and update_post hook callback */
  public function save_method( int $post_id ): array {
    // Handle validating and updating post meta.
    update_post_meta($post_id, 'acme_meta_1', $value);
  }
}

Defining Meta Data

The above Meta Box would be shown on both acme_post_type_a and acme_post_type_b
You can also inject any dependencies via the constructor too.

MetaData

You can register post, term, user and comment meta fields either as a part of Post Types/Taxonomy Registerables or on there own. This fluent object based definition makes it easy to create these inline.

You can add full REST support by supplying a schema for the field and the Registrar will register the field also.

class Additional_Post_Meta extends Additional_Meta_Data_Controller {
  /** Define the Meta Data */
  public function meta_data(array $meta_data): array {
    $meta_data[] = (new Meta_Data('meta_key'))
      ->post_type('post')
      ->default('foo')
      ->description($description)
      ->single()
      ->sanitize('sanitize_text_field')
      ->rest_schema(['type' => 'string']);

    return $meta_data;
  }
}

See full Meta Data Docs

You can also define MetaData for Post Types and Taxonomies when creating them.

Additional_Meta_Data_Controller

To register standalone Meta_Data, you can use the Additional_Meta_Data_Controller which has a single method meta_data(array $meta_data): array. Like in the example above, you add your Meta_Data instances to the array and return.

The class has an empty constructor, so you can easily inject dependencies in and make use of the App_Config meta options.

Example

You can see an example project which included a CPT, Taxonomy, Meta Box and Meta Data here

Contributions

If you would like to contribute to this project, please feel free to fork and submit a PR. If any issue doesn't exist for the problem, please create one.

Please ensure your changes to do not drop coverage lower than they currently are, unless it can not be helped (include a reason why)

To run test suite

Setup the dev environment $ composer install

  • $ composer all - This will run all the tests, static analysis and linter
  • $ composer coverage - This will produce a HTML coverage report ../coverage-report
  • $ composer analyse - This will run PHPStan on lv 8
  • $ composer sniff - This will run PHPCS with the WP Rule set.

Please note the CI Actions runs composer all on multiple PHP and WP versions. Running locally will only run with your version of PHP and latest major or WP.

License

MIT License

http://www.opensource.org/licenses/mit-license.html

Previous Versions

  • For Perique 1.4.* please use version Registerables 1.0.*
  • For Perique 1.3.* please use version Registerables 0.9.*
  • For Perique 1.0.* - 1.2.* please use Registerables version 0.8.*

Change Log

  • 2.0.2 - Bumped dependencies and extended tests to cover WP 6.3 & 6.4
  • 2.0.1 - Bumped dependencies for WP PHPStan, PHPUnit and updated the docs with links to example project.
  • 2.0.0 - Bumped support for Perique 2.0.0, added Regiserable module, but no other changes needed.
  • 1.0.0 - Bumped support for Perique 1.4.0 and finally released as 1.0.0
  • 0.9.0 - Move to compatible with Perique 1.3.*, Fixed bug where post types that use Gutenberg do not set meta_cap to true by default.
  • 0.8.2 - Fixed bug with Taxonomy Capabilities to not use fallbacks if not defined.
  • 0.8.1 - Update dev deps to cover wp6.0.0
  • 0.8.0 -
    • Renamed Post_Type::$templates to Post_Type::$template
    • Update docs
  • 0.7.2 - Improved Meta Data REST support.
  • 0.7.1 - Fixed bug where meta box hooks didn't fire due to race conditions getting current screen on init. Now deferred loading to meta box hooks on current_screen action. Extended support for RestSchema including use of the PinkCrab WP Rest Schema lib. Various other small fixes.
  • 0.7.0 - Introduced the Shared Meta Box Controller for registering meta boxes and meta data for shared post types.
  • 0.6.4 - Added in a filter for meta boxes which allows for setting of view args based on the current post being displayed. Allows for passing of meta values to the view, without using get_post_meta in the view it self.
  • 0.6.3 - Now generates meaningful errors when Post Type, Taxonomy or Meta Box fails validation.
  • 0.6.2 - Removed issue where Meta_Box Registrar was trying to create an instance of Renderable not View.
  • 0.6.1 - Removed old code and tests
  • 0.6.0 - Now works with Perique 1.0.0 and upwards. Added in Registration middleware and uses own registrars and validators rather than being part of the the base models.
  • 0.5.0 -
    • Updated to reflect Perique (Plugin Framework) 0.5.0
    • Remove Ajax from registerables
  • 0.4.4 - Added wp_die() after emitting psr7 response in ajax.
  • 0.4.3 - Fixed merge issue with meta box view data.
  • 0.4.2 - Finalised Meta_Data, can now be added for Term and Post meta's when either CPT or taxonomy defined. Added in missing tests.
  • 0.4.1 - Minor bugfixes
  • 0.4.0 - Bumped inline with core, moved to min requirements of core v0.4.0
  • 0.3.5 - Updated all code in src and tests to reflect the new Hook_Loader setup in core.
  • 0.3.4 - Removed the use !function_exists('get_current_screen') as phpScoper cant create a pollyfill due to not being loaded in global wp scope until needed. Now has custom method in meta box class to avoid.
  • 0.3.3 - Fixed version issue with Core
  • 0.3.2 - Added in missing 'hierarchical' => $this->hierarchical for taxonomy registration
  • 0.3.1 - Extended tests for 100 coverage.
  • 0.3.0 - Finalised the move to composer, v2 was skipped as larger internal changes made. External API remained unchanged
  • 0.2.beta - Moved to composer, removed Guzzle for nyholm ps7 in its place. Uses HTTP helper for PS7 responses and tests now include form-urlencode requests.