1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Send XML response back to Ajax request. |
4
|
|
|
* |
5
|
|
|
* @package WordPress |
6
|
|
|
* @since 2.1.0 |
7
|
|
|
*/ |
8
|
|
|
class WP_Ajax_Response { |
9
|
|
|
/** |
10
|
|
|
* Store XML responses to send. |
11
|
|
|
* |
12
|
|
|
* @since 2.1.0 |
13
|
|
|
* @var array |
14
|
|
|
*/ |
15
|
|
|
public $responses = array(); |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Constructor - Passes args to WP_Ajax_Response::add(). |
19
|
|
|
* |
20
|
|
|
* @since 2.1.0 |
21
|
|
|
* @see WP_Ajax_Response::add() |
22
|
|
|
* |
23
|
|
|
* @param string|array $args Optional. Will be passed to add() method. |
24
|
|
|
*/ |
25
|
|
|
public function __construct( $args = '' ) { |
26
|
|
|
if ( !empty($args) ) |
27
|
|
|
$this->add($args); |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Appends data to an XML response based on given arguments. |
32
|
|
|
* |
33
|
|
|
* With `$args` defaults, extra data output would be: |
34
|
|
|
* |
35
|
|
|
* <response action='{$action}_$id'> |
36
|
|
|
* <$what id='$id' position='$position'> |
37
|
|
|
* <response_data><![CDATA[$data]]></response_data> |
38
|
|
|
* </$what> |
39
|
|
|
* </response> |
40
|
|
|
* |
41
|
|
|
* @since 2.1.0 |
42
|
|
|
* @access public |
43
|
|
|
* |
44
|
|
|
* @param string|array $args { |
45
|
|
|
* Optional. An array or string of XML response arguments. |
46
|
|
|
* |
47
|
|
|
* @type string $what XML-RPC response type. Used as a child element of `<response>`. |
48
|
|
|
* Default 'object' (`<object>`). |
49
|
|
|
* @type string|false $action Value to use for the `action` attribute in `<response>`. Will be |
50
|
|
|
* appended with `_$id` on output. If false, `$action` will default to |
51
|
|
|
* the value of `$_POST['action']`. Default false. |
52
|
|
|
* @type int|WP_Error $id The response ID, used as the response type `id` attribute. Also |
53
|
|
|
* accepts a `WP_Error` object if the ID does not exist. Default 0. |
54
|
|
|
* @type int|false $old_id The previous response ID. Used as the value for the response type |
55
|
|
|
* `old_id` attribute. False hides the attribute. Default false. |
56
|
|
|
* @type string $position Value of the response type `position` attribute. Accepts 1 (bottom), |
57
|
|
|
* -1 (top), html ID (after), or -html ID (before). Default 1 (bottom). |
58
|
|
|
* @type string|WP_Error $data The response content/message. Also accepts a WP_Error object if the |
59
|
|
|
* ID does not exist. Default empty. |
60
|
|
|
* @type array $supplemental An array of extra strings that will be output within a `<supplemental>` |
61
|
|
|
* element as CDATA. Default empty array. |
62
|
|
|
* } |
63
|
|
|
* @return string XML response. |
64
|
|
|
*/ |
65
|
|
|
public function add( $args = '' ) { |
66
|
|
|
$defaults = array( |
67
|
|
|
'what' => 'object', 'action' => false, |
68
|
|
|
'id' => '0', 'old_id' => false, |
69
|
|
|
'position' => 1, |
70
|
|
|
'data' => '', 'supplemental' => array() |
71
|
|
|
); |
72
|
|
|
|
73
|
|
|
$r = wp_parse_args( $args, $defaults ); |
74
|
|
|
|
75
|
|
|
$position = preg_replace( '/[^a-z0-9:_-]/i', '', $r['position'] ); |
76
|
|
|
$id = $r['id']; |
77
|
|
|
$what = $r['what']; |
78
|
|
|
$action = $r['action']; |
79
|
|
|
$old_id = $r['old_id']; |
80
|
|
|
$data = $r['data']; |
81
|
|
|
|
82
|
|
|
if ( is_wp_error( $id ) ) { |
83
|
|
|
$data = $id; |
84
|
|
|
$id = 0; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
$response = ''; |
88
|
|
|
if ( is_wp_error( $data ) ) { |
89
|
|
|
foreach ( (array) $data->get_error_codes() as $code ) { |
90
|
|
|
$response .= "<wp_error code='$code'><![CDATA[" . $data->get_error_message( $code ) . "]]></wp_error>"; |
91
|
|
|
if ( ! $error_data = $data->get_error_data( $code ) ) { |
92
|
|
|
continue; |
93
|
|
|
} |
94
|
|
|
$class = ''; |
95
|
|
|
if ( is_object( $error_data ) ) { |
96
|
|
|
$class = ' class="' . get_class( $error_data ) . '"'; |
97
|
|
|
$error_data = get_object_vars( $error_data ); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
$response .= "<wp_error_data code='$code'$class>"; |
101
|
|
|
|
102
|
|
|
if ( is_scalar( $error_data ) ) { |
103
|
|
|
$response .= "<![CDATA[$error_data]]>"; |
104
|
|
|
} elseif ( is_array( $error_data ) ) { |
105
|
|
|
foreach ( $error_data as $k => $v ) { |
106
|
|
|
$response .= "<$k><![CDATA[$v]]></$k>"; |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
$response .= "</wp_error_data>"; |
111
|
|
|
} |
112
|
|
|
} else { |
113
|
|
|
$response = "<response_data><![CDATA[$data]]></response_data>"; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
$s = ''; |
117
|
|
|
if ( is_array( $r['supplemental'] ) ) { |
118
|
|
|
foreach ( $r['supplemental'] as $k => $v ) { |
119
|
|
|
$s .= "<$k><![CDATA[$v]]></$k>"; |
120
|
|
|
} |
121
|
|
|
$s = "<supplemental>$s</supplemental>"; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
if ( false === $action ) { |
125
|
|
|
$action = $_POST['action']; |
126
|
|
|
} |
127
|
|
|
$x = ''; |
128
|
|
|
$x .= "<response action='{$action}_$id'>"; // The action attribute in the xml output is formatted like a nonce action |
129
|
|
|
$x .= "<$what id='$id' " . ( false === $old_id ? '' : "old_id='$old_id' " ) . "position='$position'>"; |
130
|
|
|
$x .= $response; |
131
|
|
|
$x .= $s; |
132
|
|
|
$x .= "</$what>"; |
133
|
|
|
$x .= "</response>"; |
134
|
|
|
|
135
|
|
|
$this->responses[] = $x; |
136
|
|
|
return $x; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Display XML formatted responses. |
141
|
|
|
* |
142
|
|
|
* Sets the content type header to text/xml. |
143
|
|
|
* |
144
|
|
|
* @since 2.1.0 |
145
|
|
|
*/ |
146
|
|
|
public function send() { |
147
|
|
|
header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ) ); |
148
|
|
|
echo "<?xml version='1.0' encoding='" . get_option( 'blog_charset' ) . "' standalone='yes'?><wp_ajax>"; |
149
|
|
|
foreach ( (array) $this->responses as $response ) |
150
|
|
|
echo $response; |
151
|
|
|
echo '</wp_ajax>'; |
152
|
|
|
if ( wp_doing_ajax() ) |
153
|
|
|
wp_die(); |
154
|
|
|
else |
155
|
|
|
die(); |
|
|
|
|
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
|
An exit expression should only be used in rare cases. For example, if you write a short command line script.
In most cases however, using an
exit
expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.