summaryrefslogtreecommitdiff
blob: 4675876694f561b203ecc8bad9ddc8e5cf0f8e1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
/**
 * The fallback buffer for users with no XML support.
 *
 * @since 5.3.0
 * @package Jetpack
 */

/**
 * A buffer for constructing master sitemap xml files.
 *
 * @since 5.1.0
 */
abstract class Jetpack_Sitemap_Buffer_Fallback extends Jetpack_Sitemap_Buffer {

	/**
	 * The buffer contents.
	 *
	 * @access protected
	 * @since 5.3.0
	 * @var string The buffer contents.
	 */
	protected $buffer;

	public function __construct( $item_limit, $byte_limit, $time = '1970-01-01 00:00:00' ) {
		$this->is_full_flag  = false;
		$this->is_empty_flag = true;
		$this->timestamp     = $time;

		$this->finder = new Jetpack_Sitemap_Finder();

		$this->item_capacity = max( 1, intval( $item_limit ) );
		$this->byte_capacity = max( 1, intval( $byte_limit ) ) - strlen( $this->contents() );
	}

	/**
	 * Append an item to the buffer, if there is room for it,
	 * and set is_empty_flag to false. If there is no room,
	 * we set is_full_flag to true. If $item is null,
	 * don't do anything and report success.
	 *
	 * @since 5.3.0
	 *
	 * @param array $array The item to be added.
	 *
	 * @return bool True if the append succeeded, False if not.
	 */
	public function append( $array ) {
		if ( is_null( $array ) ) {
			return true;
		}

		if ( $this->is_full_flag ) {
			return false;
		}

		if ( 0 >= $this->item_capacity || 0 >= $this->byte_capacity ) {
			$this->is_full_flag = true;
			return false;
		} else {
			$this->item_capacity -= 1;
			$added_string         = $this->array_to_xml_string( $array );
			$this->buffer        .= $added_string;
			$this->is_empty_flag  = false;

			mbstring_binary_safe_encoding(); // So we can safely use strlen().
			$this->byte_capacity -= strlen( $added_string );
			reset_mbstring_encoding();

			return true;
		}
	}

	/**
	 * Detect whether the buffer is empty.
	 *
	 * @since 5.3.0
	 *
	 * @return bool True if the buffer is empty, false otherwise.
	 */
	public function is_empty() {
		return $this->is_empty_flag;
	}

	/**
	 * Retrieve the contents of the buffer.
	 *
	 * @since 5.3.0
	 *
	 * @return string The contents of the buffer (with the footer included).
	 */
	public function contents() {
		$root = $this->get_root_element();

		return '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL . $root[0] . $this->buffer . $root[1] . PHP_EOL;
	}

	/**
	 * Legacy implementation of array to XML conversion without using DOMDocument.
	 *
	 * @param Array $array
	 * @return String $result
	 */
	public function array_to_xml_string( $array, $parent = null, $root = null ) {
		$string = '';

		foreach ( $array as $key => $value ) {
			// Only allow a-z, A-Z, colon, underscore, and hyphen.
			$tag = preg_replace( '/[^a-zA-Z:_-]/', '_', $key );

			if ( is_array( $value ) ) {
				$string .= "<$tag>";
				$string .= $this->array_to_xml_string( $value );
				$string .= "</$tag>";
			} elseif ( is_null( $value ) ) {
				$string .= "<$tag />";
			} else {
				$string .= "<$tag>" . htmlspecialchars( $value ) . "</$tag>";
			}
		}

		return $string;
	}

	/**
	 * Render an associative array of XML attribute key/value pairs.
	 *
	 * @access public
	 * @since 5.3.0
	 *
	 * @param array $array Key/value array of attributes.
	 *
	 * @return string The rendered attribute string.
	 */
	public static function array_to_xml_attr_string( $array ) {
		$string = '';

		foreach ( $array as $key => $value ) {
			$key     = preg_replace( '/[^a-zA-Z:_-]/', '_', $key );
			$string .= ' ' . $key . '="' . esc_attr( $value ) . '"';
		}

		return $string;
	}

}