diff --git a/lib/Cleantalk/ApbctWP/ContactsEncoder/ContactsEncoder.php b/lib/Cleantalk/ApbctWP/ContactsEncoder/ContactsEncoder.php index 6c60fb2bd..f3591133c 100644 --- a/lib/Cleantalk/ApbctWP/ContactsEncoder/ContactsEncoder.php +++ b/lib/Cleantalk/ApbctWP/ContactsEncoder/ContactsEncoder.php @@ -30,6 +30,11 @@ class ContactsEncoder extends \Cleantalk\Common\ContactsEncoder\ContactsEncoder */ private $privacy_policy_hook_handled = false; + /** + * @var bool + */ + private $buffer_modified = false; + /** * @var string[] */ @@ -84,9 +89,23 @@ public function runEncoding($content = '') if ($apbct->settings['data__email_decoder_buffer'] && !apbct_is_ajax() && !apbct_is_rest() && !apbct_is_post() && !is_admin()) { add_action('wp', 'apbct_buffer__start'); add_action('shutdown', 'apbct_buffer__end', 0); // Collect $apbct->buffer - add_action('shutdown', array($this, 'modifyBuffer'), 2); // Modify $apbct->buffer by `ContactsEncoder::modifyBuffer` - $this->shortcodes->addActionsAfterModify('shutdown', 3); // Modify $apbct->buffer by `ShortCodesService::addActionsAfterModify` + add_action('shutdown', array($this, 'modifyBuffer'), 1); // Before apbct_buffer__output (priority 2) add_action('shutdown', array($this, 'bufferOutput'), 999); // Output $apbct->buffer + + foreach ( $hooks_to_encode as $hook ) { + if ( $hook === 'render_block' ) { + // Post content is handled on the_content after do_blocks (priority 9). + continue; + } + if ( $hook === 'the_content' ) { + // Priority 9 runs after do_blocks (9) when registered from init — placeholders keep
wrappers. + $this->shortcodes->addActionsBeforeModify($hook, 9); + $this->shortcodes->addActionsAfterModifyEncodeOnly($hook, 999); + continue; + } + $this->shortcodes->addActionsBeforeModify($hook, 9); + $this->shortcodes->addActionsAfterModifyEncodeOnly($hook, 999); + } } else { foreach ( $hooks_to_encode as $hook ) { $this->shortcodes->addActionsBeforeModify($hook, 9); @@ -180,12 +199,13 @@ private function handlePrivacyPolicyHook() public function modifyBuffer() { global $apbct; - static $already_output = false; - if ($already_output) { + if ($this->buffer_modified) { return; } - $already_output = true; + $this->buffer_modified = true; + $apbct->buffer = $this->shortcodes->modifyBufferBefore($apbct->buffer); $apbct->buffer = $this->modifyContent($apbct->buffer); + $apbct->buffer = $this->shortcodes->modifyBufferAfter($apbct->buffer); } public function bufferOutput() diff --git a/lib/Cleantalk/ApbctWP/ContactsEncoder/Exclusions/ExclusionsService.php b/lib/Cleantalk/ApbctWP/ContactsEncoder/Exclusions/ExclusionsService.php index 3c0ab6560..2ec4da70d 100644 --- a/lib/Cleantalk/ApbctWP/ContactsEncoder/Exclusions/ExclusionsService.php +++ b/lib/Cleantalk/ApbctWP/ContactsEncoder/Exclusions/ExclusionsService.php @@ -43,6 +43,10 @@ class ExclusionsService extends \Cleantalk\Common\ContactsEncoder\Exclusions\Exc public function doReturnContentBeforeModify($content) { + if ( $this->byDecoderPassedCookie() ) { + return 'byDecoderPassedCookie'; + } + if ( $this->byUrlOnHooks() ) { return 'byUrlOnHooks'; } @@ -54,6 +58,43 @@ public function doReturnContentBeforeModify($content) return parent::doReturnContentBeforeModify($content); } + /** + * Exclusions for shortcode placeholder pipeline. + * Unlike doReturnContentBeforeModify(), not blocked when global email/phone encoding is off. + * + * @param string $content + * + * @return string|false + */ + public function doReturnShortcodeContentBeforeModify($content) + { + if ( $this->byUrlOnHooks() ) { + return 'byUrlOnHooks'; + } + + if ( $this->byContentSigns($content) ) { + return 'byContentSigns'; + } + + if ( $this->byLoggedIn() ) { + return 'byLoggedIn'; + } + + if ( empty($content) || ! is_string($content) ) { + return 'byEmptyContent'; + } + + return false; + } + + /** + * @return bool + */ + protected function byLoggedIn() + { + return $this->params->is_logged_in; + } + /** * @inerhitDoc */ @@ -90,12 +131,6 @@ public function doSkipBeforeModifyingHooksAdded() */ private function byServerVars() { - // Excluded request by alt cookie - $apbct_email_encoder_passed = Cookie::get('apbct_email_encoder_passed'); - if ( $apbct_email_encoder_passed === apbct_get_email_encoder_pass_key() ) { - return true; - } - if ( apbct_is_plugin_active('ultimate-member/ultimate-member.php') && isset($_POST['um_request']) && @@ -109,6 +144,18 @@ private function byServerVars() return false; } + /** + * User passed email encoder check — skip encoding but keep shortcode layout hooks. + * + * @return bool + */ + private function byDecoderPassedCookie() + { + $apbct_email_encoder_passed = Cookie::get('apbct_email_encoder_passed'); + + return $apbct_email_encoder_passed === apbct_get_email_encoder_pass_key(); + } + /** * @param State $apbct * diff --git a/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/EncodeContentSC.php b/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/EncodeContentSC.php index 6c9e1a75e..e12d85fa8 100644 --- a/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/EncodeContentSC.php +++ b/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/EncodeContentSC.php @@ -6,7 +6,7 @@ use Cleantalk\ApbctWP\Escape; use Cleantalk\ApbctWP\Variables\Cookie; use Cleantalk\Common\ContactsEncoder\Dto\Params; -use Cleantalk\Common\ContactsEncoder\Exclusions\ExclusionsService; +use Cleantalk\ApbctWP\ContactsEncoder\Exclusions\ExclusionsService; /** * Shortcode to encode any string content. @@ -99,7 +99,7 @@ public function callback($_atts, $content, $_tag) */ public function changeContentBeforeEncoderModify($content) { - if ( $this->exclusions->doReturnContentBeforeModify($content) ) { + if ( $this->exclusions->doReturnShortcodeContentBeforeModify($content) ) { return $content; } @@ -146,6 +146,19 @@ public function changeContentAfterEncoderModify($content) foreach ($this->shortcode_replacements as $placeholder => $original) { $content = str_replace($placeholder, $original, $content); } - return $this->doCallbackAction($content); + + $result = $this->doCallbackAction($content); + $this->resetShortcodeReplacements(); + + return $result; + } + + /** + * @return void + */ + public function resetShortcodeReplacements() + { + $this->shortcode_replacements = array(); + $this->shortcode_counter = 0; } } diff --git a/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/ExcludedEncodeContentSC.php b/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/ExcludedEncodeContentSC.php index b39dc37c0..6d431d45e 100644 --- a/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/ExcludedEncodeContentSC.php +++ b/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/ExcludedEncodeContentSC.php @@ -53,7 +53,12 @@ public function changeContentAfterEncoderModify($content) } if ( $apbct->settings['data__email_decoder_buffer'] ) { - $content = $apbct->buffer; + if ( $this->getCurrentAction() !== 'shutdown' ) { + return $content; + } + if ( $content === '' || $content === null ) { + $content = $apbct->buffer; + } } // Skip processing if shortcode is inside an HTML tag to prevent attribute injection diff --git a/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/ShortCodesService.php b/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/ShortCodesService.php index ad41d2c1f..ebacb45a8 100644 --- a/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/ShortCodesService.php +++ b/lib/Cleantalk/ApbctWP/ContactsEncoder/Shortcodes/ShortCodesService.php @@ -25,7 +25,8 @@ public function registerAll() if (!$this->shortcodes_registered) { $this->encode->register(); if ( ! $apbct->settings['data__email_decoder_buffer'] ) { - // If buffer is active, Do not run wordpress shortcode replacement - encoder do it itself here `ExcludedEncodeContentSC::changeContentAfterEncoderModify` + // If buffer is active, do not run WordPress shortcode replacement - + // encoder processes apbct_skip_encoding in modifyBufferAfter(). $this->shortcode_to_exclude->register(); } $this->shortcodes_registered = true; @@ -48,4 +49,49 @@ public function addActionsAfterModify($hook, $priority = 999) add_filter($hook, array($this->encode, 'changeContentAfterEncoderModify'), $priority); add_filter($hook, array($this->shortcode_to_exclude, 'changeContentAfterEncoderModify'), $priority); } + + public function addActionsAfterModifyEncodeOnly($hook, $priority = 999) + { + add_filter($hook, array($this->encode, 'changeContentAfterEncoderModify'), $priority); + } + + /** + * Prepare output buffer content before ContactsEncoder::modifyContent(). + * + * @param string $buffer + * + * @return string + */ + public function modifyBufferBefore($buffer) + { + $this->encode->resetShortcodeReplacements(); + + return $this->encode->changeContentBeforeEncoderModify($buffer); + } + + /** + * Finalize output buffer content after ContactsEncoder::modifyContent(). + * + * @param string $buffer + * + * @return string + */ + public function modifyBufferAfter($buffer) + { + global $apbct; + + $buffer = $this->encode->changeContentAfterEncoderModify($buffer); + + if ( $apbct->settings['data__email_decoder_buffer'] ) { + $apbct->buffer = $buffer; + } + + $buffer = $this->shortcode_to_exclude->changeContentAfterEncoderModify($buffer); + + if ( $apbct->settings['data__email_decoder_buffer'] ) { + return $apbct->buffer; + } + + return $buffer; + } } diff --git a/tests/ApbctWP/ContactsEncoder/Shortcodes/ExcludedEncodeContentSCTest.php b/tests/ApbctWP/ContactsEncoder/Shortcodes/ExcludedEncodeContentSCTest.php index 34ecb6350..38479a03e 100644 --- a/tests/ApbctWP/ContactsEncoder/Shortcodes/ExcludedEncodeContentSCTest.php +++ b/tests/ApbctWP/ContactsEncoder/Shortcodes/ExcludedEncodeContentSCTest.php @@ -87,7 +87,32 @@ public function testChangeContentAfterEncoderModifyWithBufferOn(): void $this->contacts_encoder->dropInstance(); // Need to rebuild the object after the settings changed $this->contacts_encoder = apbctGetContactsEncoder(); - $result = $this->exclude_content_sc->changeContentAfterEncoderModify(''); + $result = $this->exclude_content_sc->changeContentAfterEncoderModify($content); + + $this->assertEquals($content, $result); + } + + /** + * Test changeContentAfterEncoderModify uses apbct->buffer during shutdown when content is empty + */ + public function testChangeContentAfterEncoderModifyWithBufferOnUsesBufferDuringShutdown(): void + { + global $apbct; + + $content = 'original buffer content test@example.com'; + + $apbct->settings['data__email_decoder_buffer'] = true; + $apbct->buffer = $content; + $apbct->saveSettings(); + $this->contacts_encoder->dropInstance(); + $this->contacts_encoder = apbctGetContactsEncoder(); + + $shortcodeMock = $this->getMockBuilder(ExcludedEncodeContentSC::class) + ->setMethods(['getCurrentAction']) + ->getMock(); + $shortcodeMock->method('getCurrentAction')->willReturn('shutdown'); + + $result = $shortcodeMock->changeContentAfterEncoderModify(''); $this->assertEquals($content, $result); } @@ -134,12 +159,15 @@ public function testChangeContentAfterEncoderModifyWithMultipleShortcodes(): voi $apbct->saveSettings(); $this->contacts_encoder->dropInstance(); // Need to rebuild the object after the settings changed $this->contacts_encoder = apbctGetContactsEncoder(); - $apbct->buffer = 'buffer [apbct_skip_encoding]first[/apbct_skip_encoding] and [apbct_skip_encoding]second[/apbct_skip_encoding]'; + $buffer_content = 'buffer [apbct_skip_encoding]first[/apbct_skip_encoding] and [apbct_skip_encoding]second[/apbct_skip_encoding]'; + $apbct->buffer = $buffer_content; $shortcodeMock = $this->getMockBuilder(ExcludedEncodeContentSC::class) - ->setMethods(['callback']) + ->setMethods(['callback', 'getCurrentAction']) ->getMock(); + $shortcodeMock->method('getCurrentAction')->willReturn('shutdown'); + // Expect two calls to callback $matcher = $this->exactly(2); $shortcodeMock->expects($matcher) @@ -156,7 +184,7 @@ public function testChangeContentAfterEncoderModifyWithMultipleShortcodes(): voi return ''; }); - $result = $shortcodeMock->changeContentAfterEncoderModify('input'); + $result = $shortcodeMock->changeContentAfterEncoderModify($buffer_content); $this->assertEquals('buffer decoded first and decoded second', $result); } @@ -172,17 +200,20 @@ public function testChangeContentAfterEncoderModifyWhenCallbackReturnsUnmodified $apbct->saveSettings(); $this->contacts_encoder->dropInstance(); // Need to rebuild the object after the settings changed $this->contacts_encoder = apbctGetContactsEncoder(); - $apbct->buffer = 'buffer [apbct_skip_encoding]content[/apbct_skip_encoding]'; + $buffer_content = 'buffer [apbct_skip_encoding]content[/apbct_skip_encoding]'; + $apbct->buffer = $buffer_content; $shortcodeMock = $this->getMockBuilder(ExcludedEncodeContentSC::class) - ->setMethods(['callback']) + ->setMethods(['callback', 'getCurrentAction']) ->getMock(); + $shortcodeMock->method('getCurrentAction')->willReturn('shutdown'); + $shortcodeMock->expects($this->once()) ->method('callback') ->willReturn('content'); // Return unmodified content - $result = $shortcodeMock->changeContentAfterEncoderModify('input'); + $result = $shortcodeMock->changeContentAfterEncoderModify($buffer_content); // Expect content not to change, but tags are removed $this->assertEquals('buffer content', $result); @@ -265,7 +296,7 @@ public function testChangeContentAfterEncoderModifySkipsShortcodeInsideHtmlTag() $this->contacts_encoder->dropInstance(); $this->contacts_encoder = apbctGetContactsEncoder(); - $result = $this->exclude_content_sc->changeContentAfterEncoderModify(''); + $result = $this->exclude_content_sc->changeContentAfterEncoderModify($content); // Content should be returned unchanged because shortcode is inside HTML tag $this->assertEquals($content, $result); @@ -289,7 +320,7 @@ public function testMixedShortcodesSafeAndUnsafe(): void $this->contacts_encoder->dropInstance(); $this->contacts_encoder = apbctGetContactsEncoder(); - $result = $this->exclude_content_sc->changeContentAfterEncoderModify(''); + $result = $this->exclude_content_sc->changeContentAfterEncoderModify($content); // Full block should be skipped if ANY shortcode is inside HTML tag $this->assertEquals($content, $result); diff --git a/tests/ApbctWP/ContactsEncoder/TestContactsEncoder.php b/tests/ApbctWP/ContactsEncoder/TestContactsEncoder.php index bbede4bee..e38456227 100644 --- a/tests/ApbctWP/ContactsEncoder/TestContactsEncoder.php +++ b/tests/ApbctWP/ContactsEncoder/TestContactsEncoder.php @@ -4,6 +4,7 @@ use Cleantalk\ApbctWP\ContactsEncoder\ContactsEncoder; use Cleantalk\ApbctWP\State; +use Cleantalk\ApbctWP\Variables\Cookie; use Cleantalk\Common\ContactsEncoder\Dto\Params; use PHPUnit\Framework\TestCase; @@ -22,6 +23,41 @@ public function setUp(): void global $apbct; $apbct->api_key = 'testapikey'; $this->contacts_encoder = apbctGetContactsEncoder(); + $this->clearDecoderPassedCookie(); + } + + private function clearDecoderPassedCookie(): void + { + $cookie_name = apbct__get_cookie_prefix() . 'apbct_email_encoder_passed'; + unset($_COOKIE[$cookie_name]); + + $cookie_instance = Cookie::getInstance(); + $ref = new \ReflectionClass($cookie_instance); + while ($ref) { + if ($ref->hasProperty('variables')) { + $prop = $ref->getProperty('variables'); + $prop->setAccessible(true); + $variables = $prop->getValue($cookie_instance); + unset($variables[$cookie_name]); + $prop->setValue($cookie_instance, $variables); + break; + } + $ref = $ref->getParentClass(); + } + } + + private function setDecoderPassedCookie(): string + { + global $apbct; + $apbct->data['key_is_ok'] = true; + $apbct->data['cookies_type'] = 'native'; + $pass_key = apbct_get_email_encoder_pass_key(); + $cookie_name = apbct__get_cookie_prefix() . 'apbct_email_encoder_passed'; + $this->clearDecoderPassedCookie(); + $_COOKIE[$cookie_name] = $pass_key; + Cookie::set('apbct_email_encoder_passed', $pass_key); + + return $pass_key; } public function testPlainTextEncodeDecodeSSL() @@ -262,6 +298,80 @@ public function testModifyBuffer() $this->assertNotEquals($apbct->buffer, $test_string); } + public function testModifyBufferPreservesParagraphWrapperAroundShortcode() + { + global $apbct; + + $apbct->settings['data__email_decoder_buffer'] = true; + $apbct->settings['data__email_decoder_encode_email_addresses'] = 1; + $apbct->saveSettings(); + $this->contacts_encoder->dropInstance(); + $this->contacts_encoder = apbctGetContactsEncoder(); + $this->contacts_encoder->runEncoding(); + + $apbct->buffer = '
[apbct_encode_data]any data to encode[/apbct_encode_data]
'; + $this->contacts_encoder->modifyBuffer(); + + $this->assertStringStartsWith('', $apbct->buffer); + $this->assertStringContainsString('
', $apbct->buffer); + $this->assertStringNotContainsString('[apbct_encode_data]', $apbct->buffer); + $this->assertStringContainsString('apbct-email-encoder', $apbct->buffer); + } + + public function testModifyBufferPreservesParagraphWrapperAroundPlainEmailAndShortcode() + { + global $apbct; + + $apbct->settings['data__email_decoder_buffer'] = true; + $apbct->settings['data__email_decoder_encode_email_addresses'] = 1; + $apbct->saveSettings(); + $this->contacts_encoder->dropInstance(); + $this->contacts_encoder = apbctGetContactsEncoder(); + $this->contacts_encoder->runEncoding(); + + $apbct->buffer = + 's@cleantalk.org
' . + '[apbct_encode_data]any data to encode[/apbct_encode_data]
' . + '[apbct_encode_data]plain shortcode line[/apbct_encode_data]
'; + + $this->contacts_encoder->modifyBuffer(); + + $this->assertEquals(3, substr_count($apbct->buffer, '')); + $this->assertEquals(3, substr_count($apbct->buffer, '
')); + $this->assertStringNotContainsString('[apbct_encode_data]', $apbct->buffer); + $this->assertStringContainsString('apbct-email-encoder', $apbct->buffer); + } + + public function testModifyBufferSkipsEncodingWhenDecoderCookieSet() + { + global $apbct; + + $pass_key = $this->setDecoderPassedCookie(); + + $apbct->settings['data__email_decoder_buffer'] = true; + $apbct->settings['data__email_decoder_encode_email_addresses'] = 1; + $apbct->saveSettings(); + $this->contacts_encoder->dropInstance(); + $this->contacts_encoder = apbctGetContactsEncoder(); + $this->contacts_encoder->runEncoding(); + + $this->assertEquals($pass_key, Cookie::get('apbct_email_encoder_passed')); + + $apbct->buffer = + 'any text to encode
' . + 'email test1@te.st
' . + 'text and email, email - test2@te.st
'; + + $this->contacts_encoder->modifyBuffer(); + + $this->assertEquals(3, substr_count($apbct->buffer, '')); + $this->assertEquals(3, substr_count($apbct->buffer, '
')); + $this->assertStringNotContainsString('apbct-email-encoder', $apbct->buffer); + $this->assertStringContainsString('any text to encode', $apbct->buffer); + $this->assertStringContainsString('test1@te.st', $apbct->buffer); + $this->assertStringContainsString('test2@te.st', $apbct->buffer); + } + public function testBufferOutput() { global $apbct; @@ -470,5 +580,6 @@ public function tearDown() : void { global $apbct; $apbct->buffer = ''; + $this->clearDecoderPassedCookie(); } } diff --git a/tests/ApbctWP/ContactsEncoder/TestContactsEncoderShortCodeEncode.php b/tests/ApbctWP/ContactsEncoder/TestContactsEncoderShortCodeEncode.php index 5691f12dd..2f5e98442 100644 --- a/tests/ApbctWP/ContactsEncoder/TestContactsEncoderShortCodeEncode.php +++ b/tests/ApbctWP/ContactsEncoder/TestContactsEncoderShortCodeEncode.php @@ -21,18 +21,58 @@ protected function setUp(): void */ global $apbct; $apbct->api_key = 'tetskey'; + $apbct->data['key_is_ok'] = true; $apbct->data['cookies_type'] = 'native'; $apbct->saveData(); $params = new Params(); $params->api_key = $apbct->api_key; $this->shortcode = new EncodeContentSC($params); $this->shortcode->register(); + $this->clearDecoderPassedCookie(); + } + + protected function tearDown(): void + { + $this->clearDecoderPassedCookie(); + parent::tearDown(); + } + + private function clearDecoderPassedCookie(): void + { + $cookie_name = apbct__get_cookie_prefix() . 'apbct_email_encoder_passed'; + unset($_COOKIE[$cookie_name]); + + $cookie_instance = Cookie::getInstance(); + $ref = new \ReflectionClass($cookie_instance); + while ($ref) { + if ($ref->hasProperty('variables')) { + $prop = $ref->getProperty('variables'); + $prop->setAccessible(true); + $variables = $prop->getValue($cookie_instance); + unset($variables[$cookie_name]); + $prop->setValue($cookie_instance, $variables); + break; + } + $ref = $ref->getParentClass(); + } + } + + private function setDecoderPassedCookie(): void + { + global $apbct; + $apbct->data['key_is_ok'] = true; + $apbct->data['cookies_type'] = 'native'; + $pass_key = apbct_get_email_encoder_pass_key(); + $cookie_name = apbct__get_cookie_prefix() . 'apbct_email_encoder_passed'; + $_COOKIE[$cookie_name] = $pass_key; + $this->clearDecoderPassedCookie(); + $_COOKIE[$cookie_name] = $pass_key; + Cookie::set('apbct_email_encoder_passed', $pass_key); } public function testCallbackEncodesContent() { - $_COOKIE['apbct_email_encoder_passed'] = apbct_get_email_encoder_pass_key(); - Cookie::set('apbct_email_encoder_passed', apbct_get_email_encoder_pass_key()); + $this->setDecoderPassedCookie(); $cookie = Cookie::get('apbct_email_encoder_passed'); $content = 'Test content'; $result = $this->shortcode->callback([], $content, 'apbct_encode_data'); @@ -42,8 +82,8 @@ public function testCallbackEncodesContent() public function testCallbackReturnsOriginalContentIfCookieSet() { - $_COOKIE['apbct_email_encoder_passed'] = apbct_get_email_encoder_pass_key(); - $content = 'Test content'; + $this->setDecoderPassedCookie(); + $content = 'Test content'; $result = $this->shortcode->callback([], $content, 'apbct_encode_data'); @@ -59,6 +99,32 @@ public function testChangeContentBeforeEncoderModifyReplacesShortcodesWithPlaceh $this->assertArrayHasKey('%%APBCT_SHORT_CODE_INCLUDE_EE_0%%', $this->shortcode->shortcode_replacements); } + public function testChangeContentBeforeEncoderModifyUsesPlaceholdersWhenDecoderCookieSet() + { + $this->setDecoderPassedCookie(); + + $content = 'Some content with [apbct_encode_data]Test content[/apbct_encode_data]'; + $result = $this->shortcode->changeContentBeforeEncoderModify($content); + + $this->assertStringContainsString('%%APBCT_SHORT_CODE_INCLUDE_EE_0%%', $result); + $this->assertArrayHasKey('%%APBCT_SHORT_CODE_INCLUDE_EE_0%%', $this->shortcode->shortcode_replacements); + } + + public function testChangeContentBeforeEncoderModifyUsesPlaceholdersWhenGlobalEmailEncodingDisabled() + { + $params = new Params(); + $params->api_key = 'testkey'; + $params->do_encode_emails = 0; + $params->do_encode_phones = 0; + $shortcode = new EncodeContentSC($params); + + $content = '[apbct_encode_data]Test content[/apbct_encode_data]
'; + $result = $shortcode->changeContentBeforeEncoderModify($content); + + $this->assertStringContainsString('%%APBCT_SHORT_CODE_INCLUDE_EE_0%%', $result); + $this->assertStringContainsString('', $result); + } + public function testChangeContentAfterEncoderModifyRestoresShortcodes() { $this->shortcode->shortcode_replacements = [ @@ -67,6 +133,21 @@ public function testChangeContentAfterEncoderModifyRestoresShortcodes() $content = '%%APBCT_SHORT_CODE_INCLUDE_EE_0%%'; $result = $this->shortcode->changeContentAfterEncoderModify($content); + $this->assertStringNotContainsString('[apbct_encode_data]', $result); + $this->assertStringNotContainsString('%%APBCT_SHORT_CODE_INCLUDE_EE_0%%', $result); + $this->assertStringContainsString('apbct-email-encoder', $result); + } + + public function testChangeContentAfterEncoderModifyRestoresShortcodesWithoutEncodingWhenDecoderCookieSet() + { + $this->setDecoderPassedCookie(); + + $this->shortcode->shortcode_replacements = [ + '%%APBCT_SHORT_CODE_INCLUDE_EE_0%%' => '[apbct_encode_data]Test content[/apbct_encode_data]' + ]; + $content = '%%APBCT_SHORT_CODE_INCLUDE_EE_0%%'; + $result = $this->shortcode->changeContentAfterEncoderModify($content); + $this->assertEquals('Test content', $result); }