Add personalization-tag-registry class

The new class which allows register Personalization Tags and then read them.
[MAILPOET-6328]
This commit is contained in:
Jan Lysý
2024-11-21 19:53:00 +01:00
committed by Pavel Dohnal
parent 8a32099af7
commit aab08fa5ab
4 changed files with 279 additions and 13 deletions

View File

@@ -0,0 +1,75 @@
<?php
/**
* This file is part of the MailPoet plugin.
*
* @package MailPoet\EmailEditor
*/
declare(strict_types = 1);
namespace MailPoet\EmailEditor\Engine\PersonalizationTags;
/**
* Registry for personalization tags.
*/
class Personalization_Tags_Registry {
/**
* List of registered personalization tags.
*
* @var array
*/
private $tags = array();
/**
* Initialize the personalization tags registry.
*
* @return void
*/
public function initialize(): void {
apply_filters( 'mailpoet_email_editor_register_personalization_tags', $this );
}
/**
* Register a new personalization tag.
*
* @param string $name Unique identifier for the callback.
* @param string $tag The tag to be used in the email content.
* @param string $category The category of the personalization tag.
* @param callable $callback The callable function/method.
* @param array $attributes Additional data or settings for the callback (optional).
* @return void
*/
public function register( string $name, string $tag, string $category, callable $callback, array $attributes = array() ): void {
if ( isset( $this->tags[ $tag ] ) ) {
return;
}
$this->tags[ $tag ] = array(
'tag' => $tag,
'name' => $name,
'category' => $category,
'callback' => $callback,
'attributes' => $attributes,
);
}
/**
* Retrieve a personalization tag by its tag.
*
* @param string $tag The tag of the personalization tag.
* @return array|null The array data or null if not found.
*/
public function get_by_tag( string $tag ): ?array {
return $this->tags[ $tag ] ?? null;
}
/**
* Retrieve all registered personalization tags.
*
* @return array List of all registered personalization tags.
*/
public function get_all() {
return $this->tags;
}
}

View File

@@ -9,6 +9,7 @@ declare(strict_types = 1);
namespace MailPoet\EmailEditor\Engine;
use MailPoet\EmailEditor\Engine\Patterns\Patterns;
use MailPoet\EmailEditor\Engine\PersonalizationTags\Personalization_Tags_Registry;
use MailPoet\EmailEditor\Engine\Templates\Template_Preview;
use MailPoet\EmailEditor\Engine\Templates\Templates;
use WP_Post;
@@ -61,6 +62,13 @@ class Email_Editor {
*/
private Send_Preview_Email $send_preview_email;
/**
* Property for Personalization_Tags_Controller instance.
*
* @var Personalization_Tags_Registry Personalization tags controller.
*/
private Personalization_Tags_Registry $personalization_tags_registry;
/**
* Constructor.
*
@@ -70,6 +78,7 @@ class Email_Editor {
* @param Patterns $patterns Patterns.
* @param Settings_Controller $settings_controller Settings controller.
* @param Send_Preview_Email $send_preview_email Preview email controller.
* @param Personalization_Tags_Registry $personalization_tags_controller Preview email controller.
*/
public function __construct(
Email_Api_Controller $email_api_controller,
@@ -77,7 +86,8 @@ class Email_Editor {
Template_Preview $template_preview,
Patterns $patterns,
Settings_Controller $settings_controller,
Send_Preview_Email $send_preview_email
Send_Preview_Email $send_preview_email,
Personalization_Tags_Registry $personalization_tags_controller
) {
$this->email_api_controller = $email_api_controller;
$this->templates = $templates;
@@ -85,6 +95,7 @@ class Email_Editor {
$this->patterns = $patterns;
$this->settings_controller = $settings_controller;
$this->send_preview_email = $send_preview_email;
$this->personalization_tags_registry = $personalization_tags_controller;
}
/**
@@ -99,6 +110,7 @@ class Email_Editor {
$this->register_block_patterns();
$this->register_wmail_post_types();
$this->register_email_post_send_status();
$this->register_personalization_tags();
$is_editor_page = apply_filters( 'mailpoet_is_email_editor_page', false );
if ( $is_editor_page ) {
$this->extend_email_post_api();
@@ -145,6 +157,16 @@ class Email_Editor {
}
}
/**
* Register all personalization tags registered via
* the mailpoet_email_editor_register_personalization_tags filter.
*
* @return void
*/
private function register_personalization_tags(): void {
$this->personalization_tags_registry->initialize();
}
/**
* Returns the email post types.
*

View File

@@ -0,0 +1,135 @@
<?php
/**
* This file is part of the MailPoet plugin.
*
* @package MailPoet\EmailEditor
*/
declare(strict_types = 1);
use PHPUnit\Framework\TestCase;
use MailPoet\EmailEditor\Engine\PersonalizationTags\Personalization_Tags_Registry;
/**
* Test cases for the Personalization_Tags_Registry class.
*/
class PersonalizationTagsRegistryTest extends TestCase {
/**
* Property for the personalization tags registry.
*
* @var Personalization_Tags_Registry Personalization tags registry.
*/
private $registry;
/**
* Set up the test case.
*/
protected function setUp(): void {
$this->registry = new Personalization_Tags_Registry();
}
/**
* Register tag and retrieve it.
*/
public function testRegisterAndGetTag(): void {
$callback = function () {
return 'Personalized Value';
};
// Register a tag.
$this->registry->register(
'first_name_tag',
'first_name',
'Subscriber Info',
$callback,
array( 'description' => 'First name of the subscriber' )
);
// Retrieve the tag.
$tag_data = $this->registry->get_by_tag( 'first_name' );
// Assert that the tag is registered correctly.
$this->assertNotNull( $tag_data );
$this->assertSame( 'first_name', $tag_data['tag'] );
$this->assertSame( 'first_name_tag', $tag_data['name'] );
$this->assertSame( 'Subscriber Info', $tag_data['category'] );
$this->assertSame( $callback, $tag_data['callback'] );
$this->assertSame( 'First name of the subscriber', $tag_data['attributes']['description'] );
}
/**
* Try to retrieve a tag that hasn't been registered.
*/
public function testRetrieveNonexistentTag(): void {
$this->assertNull( $this->registry->get_by_tag( 'nonexistent' ) );
}
/**
* Register multiple tags and retrieve them.
*/
public function testRegisterDuplicateTag(): void {
$callback1 = function () {
return 'Value 1';
};
$callback2 = function () {
return 'Value 2';
};
// Register a tag.
$this->registry->register( 'tag1', 'tag-1', 'Category 1', $callback1 );
// Attempt to register the same tag again.
$this->registry->register( 'tag2', 'tag-2', 'Category 2', $callback2 );
// Retrieve the tag and ensure the first registration is preserved.
$tag_data = $this->registry->get_by_tag( 'tag-1' );
$this->assertSame( 'tag1', $tag_data['name'] );
$this->assertSame( 'Category 1', $tag_data['category'] );
$this->assertSame( $callback1, $tag_data['callback'] );
}
/**
* Retrieve all registered tags.
*/
public function testGetAllTags(): void {
$callback = function () {
return 'Value';
};
// Register multiple tags.
$this->registry->register( 'tag1', 'tag-1', 'Category 1', $callback );
$this->registry->register( 'tag2', 'tag-2', 'Category 2', $callback );
// Retrieve all tags.
$all_tags = $this->registry->get_all();
// Assert the number of registered tags.
$this->assertCount( 2, $all_tags );
$this->assertArrayHasKey( 'tag-1', $all_tags );
$this->assertArrayHasKey( 'tag-2', $all_tags );
}
/**
* Initialize the registry and apply a filter.
*/
public function testInitializeAppliesFilter(): void {
// Mock WordPress's `apply_filters` function.
global $wp_filter_applied;
$wp_filter_applied = false;
add_filter(
'mailpoet_email_editor_register_personalization_tags',
function ( $registry ) use ( &$wp_filter_applied ) {
$wp_filter_applied = true;
return $registry;
}
);
// Initialize the registry.
$this->registry->initialize();
// Assert that the filter was applied.
$this->assertTrue( $wp_filter_applied );
}
}

View File

@@ -33,6 +33,40 @@ if ( ! function_exists( 'esc_html' ) ) {
}
}
if ( ! function_exists( 'add_filter' ) ) {
/**
* Mock add_filter function.
*
* @param string $tag Tag to add filter for.
* @param callable $callback Callback to call.
*/
function add_filter( $tag, $callback ) {
global $wp_filters;
if ( ! isset( $wp_filters ) ) {
$wp_filters = array();
}
$wp_filters[ $tag ][] = $callback;
}
}
if ( ! function_exists( 'apply_filters' ) ) {
/**
* Mock apply_filters function.
*
* @param string $tag Tag to apply filters for.
* @param mixed $value Value to filter.
*/
function apply_filters( $tag, $value ) {
global $wp_filters;
if ( isset( $wp_filters[ $tag ] ) ) {
foreach ( $wp_filters[ $tag ] as $callback ) {
$value = call_user_func( $callback, $value );
}
}
return $value;
}
}
/**
* Base class for unit tests.
*/