Completed
Push — fix/amp-infinite-scroll-add-hi... ( 4b4fba )
by
unknown
22:19 queued 14:03
created

Jetpack_AMP_Infinite_Scroll_Sanitizer::sanitize()   B

Complexity

Conditions 7
Paths 9

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 9
nop 0
dl 0
loc 40
rs 8.3466
c 0
b 0
f 0
1
<?php
2
/**
3
 * Infinite scroll sanitizer for AMP pages.
4
 *
5
 * @package    Jetpack
6
 * @since      9.1.0
7
 */
8
9
/**
10
 * This class makes the necessary changes to an AMP page when making an amp-next-page request.
11
 */
12
final class Jetpack_AMP_Infinite_Scroll_Sanitizer extends AMP_Base_Sanitizer {
13
14
	/**
15
	 * @var array {
16
	 *     @type string   $footer_xpaths
17
	 *     @type string[] $next_page_hide_xpaths
18
	 *     @type string[] $hidden_xpaths
19
	 * }
20
	 */
21
	protected $args;
22
23
	/**
24
	 * XPath.
25
	 *
26
	 * @var DOMXPath
27
	 */
28
	private $xpath;
29
30
	/**
31
	 * Sanitize.
32
	 */
33
	public function sanitize() {
34
		$this->xpath = new DOMXPath( $this->dom );
35
36
		// Abort if there is no amp-next-page in the document.
37
		$next_page_element = $this->xpath->query( '//amp-next-page[ @class = "jetpack-infinite-scroll" ]' )->item( 0 );
38
		if ( ! $next_page_element instanceof DOMElement ) {
39
			return;
40
		}
41
42
		// Abort amp-next-page if no footer element discovered.
43
		$footer_elements = array();
44
		if ( ! empty( $this->args['footer_xpaths'] ) ) {
45
			foreach ( $this->args['footer_xpaths'] as $footer_xpath ) {
46
				$footer_elements = array_merge( $footer_elements, iterator_to_array( $this->xpath->query( $footer_xpath ) ) );
47
			}
48
		}
49
		if ( empty( $footer_elements ) ) {
50
			return;
51
		}
52
53
		// Abort if the amp-next-page lacks a div[footer] element.
54
		$footer_container = $this->xpath->query( './div[ @footer ]', $next_page_element )->item( 0 );
55
		if ( ! $footer_container instanceof DOMElement ) {
56
			return;
57
		}
58
59
		// Make sure amp-next-page is at the end of the body.
60
		$body = $this->dom->getElementsByTagName( 'body' )->item( 0 );
61
		$next_page_element->parentNode->removeChild( $next_page_element );
62
		$body->appendChild( $next_page_element );
63
64
		// Move the footer to be inside of <amp-next-page>.
65
		foreach ( $footer_elements as $footer_element ) {
66
			$footer_element->parentNode->removeChild( $footer_element );
67
			$footer_container->appendChild( $footer_element );
68
		}
69
70
		$this->hide_next_page_elements();
71
		$this->hide_hidden_elements();
72
	}
73
74
	/**
75
	 * Hide next page elements.
76
	 */
77 View Code Duplication
	private function hide_next_page_elements() {
78
		if ( isset( $this->args['next_page_hide_xpaths'] ) && is_array( $this->args['next_page_hide_xpaths'] ) ) {
79
			$xpaths = $this->args['next_page_hide_xpaths'];
80
		} else {
81
			$xpaths = array();
82
		}
83
		$xpaths[] = '//div[ @id = "wpadminbar" ]';
84
85
		foreach ( $xpaths as $next_page_hide_xpath ) {
86
			/** @var DOMElement $element */
87
			foreach ( $this->xpath->query( $next_page_hide_xpath ) as $element ) {
88
				$element->setAttribute( 'next-page-hide', '' );
89
			}
90
		}
91
	}
92
93
	/**
94
	 * Hide elements on initial load.
95
	 */
96 View Code Duplication
	private function hide_hidden_elements() {
97
		if ( isset( $this->args['hidden_xpaths'] ) && is_array( $this->args['hidden_xpaths'] ) ) {
98
			$xpaths = $this->args['hidden_xpaths'];
99
		} else {
100
			$xpaths = array();
101
		}
102
103
		foreach ( $xpaths as $hidden_xpath ) {
104
			/** @var DOMElement $element */
105
			foreach ( $this->xpath->query( $hidden_xpath ) as $element ) {
106
				$element->setAttribute( 'hidden', '' );
107
			}
108
		}
109
	}
110
}
111