From ab1e30240a32441e013196da1b57cedbeb2b5b42 Mon Sep 17 00:00:00 2001 From: Ville Siltala Date: Fri, 26 Oct 2018 17:05:14 +0300 Subject: [PATCH 1/6] Initial commit for Codifier components functionalities --- CHANGELOG.md | 11 ++ src/Component.php | 173 ++++++++++++++++++++++++++++ src/Factory/Block.php | 120 +++++++++++++++++++ src/Field/Groupable.php | 2 +- src/Interfaces/Component.php | 72 ++++++++++++ src/Interfaces/ComponentFactory.php | 22 ++++ src/Interfaces/Renderer.php | 23 ++++ src/Renderer/PHP.php | 34 ++++++ 8 files changed, 456 insertions(+), 1 deletion(-) create mode 100644 src/Component.php create mode 100644 src/Factory/Block.php create mode 100644 src/Interfaces/Component.php create mode 100644 src/Interfaces/ComponentFactory.php create mode 100644 src/Interfaces/Renderer.php create mode 100644 src/Renderer/PHP.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d7abdec..0172349 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- ACF Codifier Components + + Components are reusable field sets. + + Components can be transformed into any type of groupable field with component factories. + * `Geniem\ACF\Factory\Block`: A factory for creating ACF Gutenberg blocks with Codifier components. + + Component rendering functionality implementing the `Geniem\ACF\Interfaces\Renderer` interface. + * `Geniem\ACF\Renderer\PHP`: Uses PHP files as templates. + ## [1.14.3] - 2018-10-18 ### Fixed diff --git a/src/Component.php b/src/Component.php new file mode 100644 index 0000000..b30436b --- /dev/null +++ b/src/Component.php @@ -0,0 +1,173 @@ +name; + } + + /** + * Getter for the title. + * + * @return string + */ + public function get_title() : string { + + return $this->title; + } + + /** + * Getter for the description. + * + * @return string + */ + public function get_description() : string { + + return $this->description; + } + + /** + * Constructor method + * + * @param array $args Arguments to give to the block on creation. + */ + public function __construct( array $args ) {} + + /** + * Set the renderer for the component. + * + * @param Renderer $renderer The renderer. + */ + public function set_renderer( Renderer $renderer ) { + $this->renderer = $renderer; + } + + /** + * Getter for the component renderer. + * + * @return Renderer + * @throws Exception An exception is thrown if the renderer is not set + * and this method is called. + */ + public function get_renderer(): Renderer { + + if ( empty( $this->renderer ) ) { + // The extending class must implement this method + // if the renderer is not set. + throw new Exception( 'You must implement get_renderer()' ); + } + return $this->renderer; + } + + /** + * Getter for the category. + * + * @return string + */ + public function get_category() : string { + return $this->category; + } + + /** + * Getter for the icon. + * + * @return string + */ + public function get_icon() : string { + return $this->icon; + } + + /** + * Getter for the keywords. + * + * @return array + */ + public function get_keywords() : array { + return $this->keywords; + } +} diff --git a/src/Factory/Block.php b/src/Factory/Block.php new file mode 100644 index 0000000..3e6772a --- /dev/null +++ b/src/Factory/Block.php @@ -0,0 +1,120 @@ +component = $component; + + if ( ! function_exists( 'acf_register_block' ) ) { + throw new Exception( 'Advanced Custom Fields must be activated!' ); + } + } + + /** + * Registers the ACF Gutenberg block with the component data. + * + * @return array The registered block data. + * + * @throws Exception ACF Codifier exception. + */ + public function create() { + $this->register_field_group(); + $block = $this->register_block(); + return $block; + } + + /** + * Register the ACF field group for the block. + * + * @throws Exception ACF Codifier exception. + */ + protected function register_field_group() { + + // Define a field group and set it to use the component fields. + $field_group = new Group( $this->component->get_title(), $this->component->get_name() ); + + $rule_group = new RuleGroup(); + $rule_group->add_rule( 'block', '==', 'acf/' . $this->component->get_name() ); + + $field_group->add_rule_group( $rule_group ); + + $field_group->add_fields( $this->component->get_fields() ); + + $field_group->register(); + } + + /** + * Register the ACF block. + * + * @return array + */ + protected function register_block() { + // Register the ACF Block. + $block = acf_register_block( + [ + 'name' => $this->component->get_name(), + 'title' => $this->component->get_title(), + 'description' => $this->component->get_description(), + 'render_callback' => [ $this, 'render' ], + 'category' => $this->component->get_category(), + 'icon' => $this->component->get_icon(), + 'keywords' => $this->component->get_keywords(), + ] + ); + + return $block; + } + + /** + * The render callback method for ACF blocks. + * Passes the data to the defined renderer and + * prints out the rendered markup. + * + * @param array $block The ACF block data. + */ + public function render( array $block = [] ) { + $renderer = $this->component->get_renderer(); + + $data = get_fields(); + + echo $renderer->render( + [ + 'data' => $data, + 'block' => $block, + ] + ); + } + +} diff --git a/src/Field/Groupable.php b/src/Field/Groupable.php index 0bc5f7f..8d50183 100644 --- a/src/Field/Groupable.php +++ b/src/Field/Groupable.php @@ -241,7 +241,7 @@ public function set_fields( $fields ) { * * @return array */ - public function get_fields() { + public function get_fields() : array { return $this->{ $this->fields_var() }; } diff --git a/src/Interfaces/Component.php b/src/Interfaces/Component.php new file mode 100644 index 0000000..e3c15f2 --- /dev/null +++ b/src/Interfaces/Component.php @@ -0,0 +1,72 @@ + Date: Tue, 21 May 2019 13:52:12 +0300 Subject: [PATCH 2/6] Fix code comments --- src/Interfaces/Component.php | 2 +- src/Interfaces/ComponentFactory.php | 2 +- src/Interfaces/Renderer.php | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Interfaces/Component.php b/src/Interfaces/Component.php index e3c15f2..9c769b5 100644 --- a/src/Interfaces/Component.php +++ b/src/Interfaces/Component.php @@ -6,7 +6,7 @@ namespace Geniem\ACF\Interfaces; /** - * Class IComponent + * Class Component * * @package Geniem\ACF */ diff --git a/src/Interfaces/ComponentFactory.php b/src/Interfaces/ComponentFactory.php index a576b2c..e43c578 100644 --- a/src/Interfaces/ComponentFactory.php +++ b/src/Interfaces/ComponentFactory.php @@ -13,7 +13,7 @@ interface ComponentFactory { /** - * IComponentManager constructor. + * ComponentManager constructor. * * @param Component $component A component class instance. */ diff --git a/src/Interfaces/Renderer.php b/src/Interfaces/Renderer.php index bdbf237..e2f8c54 100644 --- a/src/Interfaces/Renderer.php +++ b/src/Interfaces/Renderer.php @@ -1,15 +1,15 @@ Date: Wed, 5 Jun 2019 15:05:36 +0300 Subject: [PATCH 3/6] Fixed wrong namespace for Groupable --- src/Component.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Component.php b/src/Component.php index b30436b..2cd62fb 100644 --- a/src/Component.php +++ b/src/Component.php @@ -5,7 +5,7 @@ namespace Geniem\ACF; -use Geniem\ACF\Field\Groupable, +use Geniem\ACF\Field\Common\Groupable, Geniem\ACF\Interfaces\Component as ComponentInterface; use Geniem\ACF\Interfaces\Renderer; From 498538a33cfa33e4c2ceec911c0350578f99fcce Mon Sep 17 00:00:00 2001 From: Miika Arponen Date: Thu, 6 Jun 2019 15:13:36 +0300 Subject: [PATCH 4/6] Components further --- src/Component.php | 4 +-- src/Factory/Block.php | 6 +++- src/Renderer/Dust.php | 78 +++++++++++++++++++++++++++++++++++++++++++ src/Renderer/PHP.php | 34 +++++++++++++++---- 4 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 src/Renderer/Dust.php diff --git a/src/Component.php b/src/Component.php index 2cd62fb..407b782 100644 --- a/src/Component.php +++ b/src/Component.php @@ -114,9 +114,9 @@ public function get_description() : string { /** * Constructor method * - * @param array $args Arguments to give to the block on creation. + * @param array|null $args Arguments to give to the block on creation. */ - public function __construct( array $args ) {} + public function __construct( ?array $args = null ) {} /** * Set the renderer for the component. diff --git a/src/Factory/Block.php b/src/Factory/Block.php index 3e6772a..783ea6e 100644 --- a/src/Factory/Block.php +++ b/src/Factory/Block.php @@ -38,7 +38,7 @@ public function __construct( Component $component ) { $this->component = $component; if ( ! function_exists( 'acf_register_block' ) ) { - throw new Exception( 'Advanced Custom Fields must be activated!' ); + throw new Exception( 'Advanced Custom Fields version 5.8.0 or greater must be activated!' ); } } @@ -109,6 +109,10 @@ public function render( array $block = [] ) { $data = get_fields(); + if ( method_exists( $this->component, 'data' ) ) { + $data = $this->component->data( $data ); + } + echo $renderer->render( [ 'data' => $data, diff --git a/src/Renderer/Dust.php b/src/Renderer/Dust.php new file mode 100644 index 0000000..949d114 --- /dev/null +++ b/src/Renderer/Dust.php @@ -0,0 +1,78 @@ +template = $template; + } + else { + throw new \Exception( 'Template file ' . $template . ' can not be found.' ); + } + } + + /** + * Renders ACF fields with the given template file. + * + * @param array $fields ACF field values. + * + * @return string + */ + public function render( array $fields ) : string { + $compiled = self::$dust->compileFile( $this->template ); + + return self::$dust->renderTemplate( $compiled, $fields['data'] ); + } +} diff --git a/src/Renderer/PHP.php b/src/Renderer/PHP.php index 9d0f864..48d6b23 100644 --- a/src/Renderer/PHP.php +++ b/src/Renderer/PHP.php @@ -17,17 +17,37 @@ class PHP implements Renderer { /** - * Renders ACF fields with the given template file. + * Template file path. * - * @param string $template The template file path. - * @param array $fields ACF field values. + * @var string */ - public function render( string $template, array $fields ) : void { - extract( $fields ); + protected $template; - if ( file_exists( $template ) ) { - include $template; + /** + * Constructor + * + * @param string $template Path to template file. + * + * @throws \Exception If template is not found. + */ + public function __construct( string $template ) { + if ( file_exists( $template ) ) { + $this->template = $template; + } + else { + throw new \Exception( 'Template file ' . $template . ' can not be found.' ); } + } + + /** + * Renders ACF fields with the given template file. + * + * @param array $fields ACF field values. + */ + public function render( array $fields ) : void { + extract( $fields ); // phpcs:ignore + + include $this->template; } From 49cb8d2676bbae871d724c4235fec71abd335923 Mon Sep 17 00:00:00 2001 From: Miika Arponen Date: Wed, 19 Jun 2019 10:35:07 +0300 Subject: [PATCH 5/6] Better support for all Gutenberg block parameters --- CHANGELOG.md | 1 + src/Component.php | 83 +++++++++++++++++++++++++++++++++++++++---- src/Factory/Block.php | 29 +++++++++------ 3 files changed, 95 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e05bb0..a913eb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * `Geniem\ACF\Factory\Block`: A factory for creating ACF Gutenberg blocks with Codifier components. + Component rendering functionality implementing the `Geniem\ACF\Interfaces\Renderer` interface. * `Geniem\ACF\Renderer\PHP`: Uses PHP files as templates. + * `Geniem\ACF\Renderer\Dust`: Uses Dust.js template files. ## [1.16.0] - 2019-04-17 diff --git a/src/Component.php b/src/Component.php index 407b782..8cd7722 100644 --- a/src/Component.php +++ b/src/Component.php @@ -39,27 +39,26 @@ abstract class Component implements ComponentInterface { protected $title = ''; /** - * Getter for the category. + * The block category * * @var string */ protected $category = ''; /** - * Getter for the icon. + * The block icon. Can hold both the string or array representation. * - * @var string + * @var string|array */ protected $icon = ''; /** - * Getter for the keywords. + * The block keywords. * * @var array */ protected $keywords = []; - /** * Component description, shows to the user * @@ -74,6 +73,40 @@ abstract class Component implements ComponentInterface { */ protected $fields = []; + /** + * Array of post types to restrict this block type to. + * + * @var array + */ + protected $post_types = []; + + /** + * Display mode for the block. + * + * Options: auto, preview or edit. + * + * @var string + */ + protected $mode = 'preview'; + + /** + * The default block alignment. + * + * Options: left, center, right, wide or full. + * + * @var string + */ + protected $align = ''; + + /** + * An array of features for the block to support. + * + * @see https://wordpress.org/gutenberg/handbook/block-api/ + * + * @var array + */ + protected $supports = []; + /** * The renderer for this component. * @@ -156,9 +189,9 @@ public function get_category() : string { /** * Getter for the icon. * - * @return string + * @return string|array */ - public function get_icon() : string { + public function get_icon() { return $this->icon; } @@ -170,4 +203,40 @@ public function get_icon() : string { public function get_keywords() : array { return $this->keywords; } + + /** + * Getter for the post types. + * + * @return array + */ + public function get_post_types() : array { + return $this->post_types; + } + + /** + * Getter for the display mode. + * + * @return string + */ + public function get_mode() : string { + return $this->mode; + } + + /** + * Getter for the default block alignment. + * + * @return string + */ + public function get_align() : string { + return $this->align; + } + + /** + * Getter for the supported features of the block. + * + * @return array + */ + public function get_supports() : array { + return $this->supports; + } } diff --git a/src/Factory/Block.php b/src/Factory/Block.php index 783ea6e..3eb9f70 100644 --- a/src/Factory/Block.php +++ b/src/Factory/Block.php @@ -81,18 +81,25 @@ protected function register_field_group() { * @return array */ protected function register_block() { + $args = [ + 'name' => $this->component->get_name(), + 'title' => $this->component->get_title(), + 'description' => $this->component->get_description(), + 'render_callback' => [ $this, 'render' ], + 'category' => $this->component->get_category(), + 'icon' => $this->component->get_icon(), + 'keywords' => $this->component->get_keywords(), + 'mode' => $this->component->get_mode(), + 'align' => $this->component->get_align(), + 'supports' => $this->component->get_supports(), + ]; + + if ( ! empty( $this->component->get_post_types() ) ) { + $args['post_types'] = $this->component->get_post_types(); + } + // Register the ACF Block. - $block = acf_register_block( - [ - 'name' => $this->component->get_name(), - 'title' => $this->component->get_title(), - 'description' => $this->component->get_description(), - 'render_callback' => [ $this, 'render' ], - 'category' => $this->component->get_category(), - 'icon' => $this->component->get_icon(), - 'keywords' => $this->component->get_keywords(), - ] - ); + $block = acf_register_block( $args ); return $block; } From bb25bd779e238d534fe4f445ce4bfb23a794526c Mon Sep 17 00:00:00 2001 From: Amanda Date: Thu, 15 Aug 2019 14:28:12 +0300 Subject: [PATCH 6/6] get_icon as string --- src/Component.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Component.php b/src/Component.php index 8cd7722..66fcacb 100644 --- a/src/Component.php +++ b/src/Component.php @@ -189,9 +189,9 @@ public function get_category() : string { /** * Getter for the icon. * - * @return string|array + * @return string */ - public function get_icon() { + public function get_icon() : string { return $this->icon; }