diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index a44401b..e0460ec 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -274,7 +274,6 @@ public function refresh_token(string $refreshToken, string $redirectURI) * @param string $url URL of HTML page. * * @throws \InvalidArgumentException If the URL is not a valid URL format. - * @throws \Exception If parsing the legacy form or landing page failed. * * @return false|string */ @@ -328,21 +327,11 @@ public function get_resource(string $url) $this->convert_relative_to_absolute_urls($html->getElementsByTagName('script'), 'src', $url_scheme_host_only); $this->convert_relative_to_absolute_urls($html->getElementsByTagName('form'), 'action', $url_scheme_host_only); - // Save HTML. - $resource = $html->saveHTML(); - - // If the result is false, return a blank string. - if (!$resource) { - throw new \Exception(sprintf('Could not parse %s', $url)); - } - // Remove some HTML tags that DOMDocument adds, returning the output. // We do this instead of using LIBXML_HTML_NOIMPLIED in loadHTML(), because Legacy Forms // are not always contained in a single root / outer element, which is required for // LIBXML_HTML_NOIMPLIED to correctly work. - $resource = $this->strip_html_head_body_tags($resource); - - return $resource; + return $this->get_body_html($html); } /** diff --git a/src/ConvertKit_API_Traits.php b/src/ConvertKit_API_Traits.php index efc67ab..2c7f035 100644 --- a/src/ConvertKit_API_Traits.php +++ b/src/ConvertKit_API_Traits.php @@ -308,6 +308,21 @@ public function add_subscriber_to_form(int $form_id, int $subscriber_id, string ); } + /** + * Adds a subscriber to a legacy form by subscriber ID + * + * @param integer $form_id Legacy Form ID. + * @param integer $subscriber_id Subscriber ID. + * + * @since 2.0.0 + * + * @return false|mixed + */ + public function add_subscriber_to_legacy_form(int $form_id, int $subscriber_id) + { + return $this->post(sprintf('landing_pages/%s/subscribers/%s', $form_id, $subscriber_id)); + } + /** * List subscribers for a form * @@ -1914,8 +1929,13 @@ public function get_segments( */ public function convert_relative_to_absolute_urls(\DOMNodeList $elements, string $attribute, string $url) // phpcs:ignore Squiz.Commenting.FunctionComment.IncorrectTypeHint, Generic.Files.LineLength.TooLong { - // Anchor hrefs. + // Store DOMNodeList in array, as iteration stops if a node is modified. + $nodes = []; foreach ($elements as $element) { + $nodes[] = $element; + } + + foreach ($nodes as $element) { // Skip if the attribute's value is empty. if (empty($element->getAttribute($attribute))) { continue; @@ -1931,31 +1951,43 @@ public function convert_relative_to_absolute_urls(\DOMNodeList $elements, string continue; } + // Remove element if it's rocket-loader.min.js. Including it prevents landing page redirects from working. + if (strpos($element->getAttribute($attribute), 'rocket-loader.min.js') !== false) { + if ($element->parentNode instanceof \DOMNode) { + $element->parentNode->removeChild($element); + } + continue; + } + // If here, the attribute's value is a relative URL, missing the http(s) and domain. // Prepend the URL to the attribute's value. $element->setAttribute($attribute, $url . $element->getAttribute($attribute)); - } + }//end foreach } /** - * Strips , and opening and closing tags from the given markup, - * as well as the Content-Type meta tag we might have added in get_html(). + * Returns the HTML within the DOMDocument's tag as a string. + * + * @param \DOMDocument $dom DOM Document. * - * @param string $markup HTML Markup. + * @since 2.1.0 * - * @return string HTML Markup + * @return string */ - public function strip_html_head_body_tags(string $markup) + public function get_body_html(\DOMDocument $dom) { - $markup = str_replace('', '', $markup); - $markup = str_replace('', '', $markup); - $markup = str_replace('', '', $markup); - $markup = str_replace('', '', $markup); - $markup = str_replace('', '', $markup); - $markup = str_replace('', '', $markup); - $markup = str_replace('', '', $markup); - - return $markup; + $body = $dom->getElementsByTagName('body')->item(0); + + if (! $body instanceof \DOMElement) { + return ''; + } + + $html = ''; + foreach ($body->childNodes as $child) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + $html .= $dom->saveHTML($child); + } + + return $html; } /** diff --git a/tests/ConvertKitMethodsTest.php b/tests/ConvertKitMethodsTest.php new file mode 100644 index 0000000..5152d1c --- /dev/null +++ b/tests/ConvertKitMethodsTest.php @@ -0,0 +1,132 @@ +api = new ConvertKit_API(); + } + + /** + * Test the convert_relative_to_absolute_urls() method. + * + * @since 2.4.1 + * + * @return void + */ + public function testConvertRelativeToAbsoluteUrls() + { + // Setup HTML in DOMDocument. + $html = new \DOMDocument(); + $html->loadHTML(' + + + + + + Test + + +
Test
+ + '); + + // Define URL to prepend to relative URLs. + $url_scheme_host_only = 'https://example.com'; + + // Convert relative URLs to absolute URLs for elements we want to test. + $this->api->convert_relative_to_absolute_urls( + $html->getElementsByTagName('a'), + 'href', + $url_scheme_host_only + ); + $this->api->convert_relative_to_absolute_urls( + $html->getElementsByTagName('link'), + 'href', + $url_scheme_host_only + ); + $this->api->convert_relative_to_absolute_urls( + $html->getElementsByTagName('img'), + 'src', + $url_scheme_host_only + ); + $this->api->convert_relative_to_absolute_urls( + $html->getElementsByTagName('script'), + 'src', + $url_scheme_host_only + ); + $this->api->convert_relative_to_absolute_urls( + $html->getElementsByTagName('form'), + 'action', + $url_scheme_host_only + ); + + // Fetch HTML string. + $output = $html->saveHTML(); + + // Assert string contains expected HTML elements that should not be modified. + $this->assertStringContainsString('', $output); + + // Assert string does not contain HTML elements that should be removed. + $this->assertStringNotContainsString( + '', + $output + ); + + // Assert string contains expected HTML elements that should be modified. + $this->assertStringContainsString( + 'Test', + $output + ); + $this->assertStringContainsString( + '', + $output + ); + $this->assertStringContainsString( + '', + $output + ); + $this->assertStringContainsString( + '
Test
', + $output + ); + } + + /** + * Test that the get_body_html() method returns the expected HTML. + * + * @since 2.4.1 + */ + public function testGetBodyHtml() + { + $content = '

Vantar þinn ungling sjálfstraust í stærðfræði?

This is a test

'; + $html = new \DOMDocument(); + $html->loadHTML(' + + ' . $content . ' + '); + $this->assertEquals($content, $this->api->get_body_html($html)); + } +}