Add new class extending WP_HTML_Tag_Processor
The new class allows replacing tokens which is necessary for Personalization Tags implementation. [MAILPOET-6328]
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of the MailPoet plugin.
|
||||||
|
*
|
||||||
|
* @package MailPoet\EmailEditor
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace MailPoet\EmailEditor\Engine\PersonalizationTags;
|
||||||
|
|
||||||
|
use WP_HTML_Tag_Processor;
|
||||||
|
use WP_HTML_Text_Replacement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class based on WP_HTML_Tag_Processor which is extended to replace
|
||||||
|
* tokens with their values in the email content.
|
||||||
|
*/
|
||||||
|
class HTML_Tag_Processor extends WP_HTML_Tag_Processor {
|
||||||
|
/**
|
||||||
|
* List of deferred updates.
|
||||||
|
*
|
||||||
|
* @var WP_HTML_Text_Replacement[]
|
||||||
|
*/
|
||||||
|
private $deferred_updates = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the token with the new content.
|
||||||
|
*
|
||||||
|
* @param string $new_content The new content to replace the token.
|
||||||
|
*/
|
||||||
|
public function replace_token( string $new_content ): void {
|
||||||
|
$this->set_bookmark( 'here' );
|
||||||
|
$here = $this->bookmarks['here'];
|
||||||
|
$this->deferred_updates[] = new WP_HTML_Text_Replacement(
|
||||||
|
$here->start,
|
||||||
|
$here->length,
|
||||||
|
$new_content
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes the deferred updates to the lexical updates.
|
||||||
|
*/
|
||||||
|
public function flush_updates(): void {
|
||||||
|
foreach ( $this->deferred_updates as $key => $update ) {
|
||||||
|
$this->lexical_updates[] = $update;
|
||||||
|
unset( $this->deferred_updates[ $key ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of the MailPoet plugin.
|
||||||
|
*
|
||||||
|
* @package MailPoet\EmailEditor
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
namespace MailPoet\EmailEditor\Engine\PersonalizationTags;
|
||||||
|
|
||||||
|
use WP_HTML_Text_Replacement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration test for HTML_Tag_Processor class which tests the token replacement.
|
||||||
|
*/
|
||||||
|
class HTMLTagProcessorTest extends \MailPoetTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test replacing a token and deferring updates.
|
||||||
|
*/
|
||||||
|
public function testReplaceToken(): void {
|
||||||
|
// Example HTML content to process.
|
||||||
|
$html_content = '<div>Hello!</div>';
|
||||||
|
|
||||||
|
// Instantiate the HTML_Tag_Processor with the HTML content.
|
||||||
|
$processor = new HTML_Tag_Processor( $html_content );
|
||||||
|
$processor->next_token();
|
||||||
|
// Replace the token.
|
||||||
|
$processor->replace_token( 'John!' );
|
||||||
|
|
||||||
|
// Verify deferred updates.
|
||||||
|
$deferred_updates = $this->getPrivateProperty( $processor, 'deferred_updates' );
|
||||||
|
|
||||||
|
$this->assertCount( 1, $deferred_updates );
|
||||||
|
$this->assertInstanceOf( WP_HTML_Text_Replacement::class, $deferred_updates[0] );
|
||||||
|
$this->assertSame( 0, $deferred_updates[0]->start );
|
||||||
|
$this->assertSame( 5, $deferred_updates[0]->length );
|
||||||
|
$this->assertSame( 'John!', $deferred_updates[0]->text );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test flushing updates.
|
||||||
|
*/
|
||||||
|
public function testFlushUpdates(): void {
|
||||||
|
// Example HTML content to process.
|
||||||
|
$html_content = '<div>Hello!</div>';
|
||||||
|
|
||||||
|
// Instantiate the HTML_Tag_Processor with the HTML content.
|
||||||
|
$processor = new HTML_Tag_Processor( $html_content );
|
||||||
|
|
||||||
|
// Mock deferred updates.
|
||||||
|
$this->setPrivateProperty(
|
||||||
|
$processor,
|
||||||
|
'deferred_updates',
|
||||||
|
array(
|
||||||
|
new WP_HTML_Text_Replacement( 0, 3, 'Hi!' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Flush the updates.
|
||||||
|
$processor->flush_updates();
|
||||||
|
|
||||||
|
// Verify lexical updates.
|
||||||
|
$lexical_updates = $this->getPrivateProperty( $processor, 'lexical_updates' );
|
||||||
|
|
||||||
|
$this->assertCount( 1, $lexical_updates );
|
||||||
|
$this->assertSame( 'Hi!', $lexical_updates[0]->text );
|
||||||
|
|
||||||
|
// Verify deferred updates are cleared.
|
||||||
|
$deferred_updates = $this->getPrivateProperty( $processor, 'deferred_updates' );
|
||||||
|
$this->assertEmpty( $deferred_updates );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to access private properties via reflection.
|
||||||
|
*
|
||||||
|
* @param object $instance The object instance.
|
||||||
|
* @param string $property The property name.
|
||||||
|
* @return mixed The property value.
|
||||||
|
*/
|
||||||
|
private function getPrivateProperty( object $instance, string $property ) {
|
||||||
|
$reflection = new \ReflectionClass( $instance );
|
||||||
|
$prop = $reflection->getProperty( $property );
|
||||||
|
$prop->setAccessible( true );
|
||||||
|
return $prop->getValue( $instance );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to set private properties via reflection.
|
||||||
|
*
|
||||||
|
* @param object $instance The object instance.
|
||||||
|
* @param string $property The property name.
|
||||||
|
* @param mixed $value The value to set.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function setPrivateProperty( object $instance, string $property, $value ): void {
|
||||||
|
$reflection = new \ReflectionClass( $instance );
|
||||||
|
$prop = $reflection->getProperty( $property );
|
||||||
|
$prop->setAccessible( true );
|
||||||
|
$prop->setValue( $instance, $value );
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user