WordPress 4.0
[autoinstalls/wordpress.git] / wp-includes / class-wp-ajax-response.php
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          * @access private
15          */
16         private $responses = array();
17
18         /**
19          * Constructor - Passes args to {@link WP_Ajax_Response::add()}.
20          *
21          * @since 2.1.0
22          * @see WP_Ajax_Response::add()
23          *
24          * @param string|array $args Optional. Will be passed to add() method.
25          * @return WP_Ajax_Response
26          */
27         public function __construct( $args = '' ) {
28                 if ( !empty($args) )
29                         $this->add($args);
30         }
31
32         /**
33          * Make private properties readable for backwards compatibility.
34          *
35          * @since 4.0.0
36          * @access public
37          *
38          * @param string $name Property to get.
39          * @return mixed Property.
40          */
41         public function __get( $name ) {
42                 return $this->$name;
43         }
44
45         /**
46          * Make private properties settable for backwards compatibility.
47          *
48          * @since 4.0.0
49          * @access public
50          *
51          * @param string $name  Property to set.
52          * @param mixed  $value Property value.
53          * @return mixed Newly-set property.
54          */
55         public function __set( $name, $value ) {
56                 return $this->$name = $value;
57         }
58
59         /**
60          * Make private properties checkable for backwards compatibility.
61          *
62          * @since 4.0.0
63          * @access public
64          *
65          * @param string $name Property to check if set.
66          * @return bool Whether the property is set.
67          */
68         public function __isset( $name ) {
69                 return isset( $this->$name );
70         }
71
72         /**
73          * Make private properties un-settable for backwards compatibility.
74          *
75          * @since 4.0.0
76          * @access public
77          *
78          * @param string $name Property to unset.
79          */
80         public function __unset( $name ) {
81                 unset( $this->$name );
82         }
83
84         /**
85          * Append to XML response based on given arguments.
86          *
87          * The arguments that can be passed in the $args parameter are below. It is
88          * also possible to pass a WP_Error object in either the 'id' or 'data'
89          * argument. The parameter isn't actually optional, content should be given
90          * in order to send the correct response.
91          *
92          * 'what' argument is a string that is the XMLRPC response type.
93          * 'action' argument is a boolean or string that acts like a nonce.
94          * 'id' argument can be WP_Error or an integer.
95          * 'old_id' argument is false by default or an integer of the previous ID.
96          * 'position' argument is an integer or a string with -1 = top, 1 = bottom,
97          * html ID = after, -html ID = before.
98          * 'data' argument is a string with the content or message.
99          * 'supplemental' argument is an array of strings that will be children of
100          * the supplemental element.
101          *
102          * @since 2.1.0
103          *
104          * @param string|array $args Override defaults.
105          * @return string XML response.
106          */
107         public function add( $args = '' ) {
108                 $defaults = array(
109                         'what' => 'object', 'action' => false,
110                         'id' => '0', 'old_id' => false,
111                         'position' => 1,
112                         'data' => '', 'supplemental' => array()
113                 );
114
115                 $r = wp_parse_args( $args, $defaults );
116
117                 $position = preg_replace( '/[^a-z0-9:_-]/i', '', $r['position'] );
118                 $id = $r['id'];
119                 $what = $r['what'];
120                 $action = $r['action'];
121                 $old_id = $r['old_id'];
122                 $data = $r['data'];
123
124                 if ( is_wp_error( $id ) ) {
125                         $data = $id;
126                         $id = 0;
127                 }
128
129                 $response = '';
130                 if ( is_wp_error( $data ) ) {
131                         foreach ( (array) $data->get_error_codes() as $code ) {
132                                 $response .= "<wp_error code='$code'><![CDATA[" . $data->get_error_message( $code ) . "]]></wp_error>";
133                                 if ( ! $error_data = $data->get_error_data( $code ) ) {
134                                         continue;
135                                 }
136                                 $class = '';
137                                 if ( is_object( $error_data ) ) {
138                                         $class = ' class="' . get_class( $error_data ) . '"';
139                                         $error_data = get_object_vars( $error_data );
140                                 }
141
142                                 $response .= "<wp_error_data code='$code'$class>";
143
144                                 if ( is_scalar( $error_data ) ) {
145                                         $response .= "<![CDATA[$error_data]]>";
146                                 } elseif ( is_array( $error_data ) ) {
147                                         foreach ( $error_data as $k => $v ) {
148                                                 $response .= "<$k><![CDATA[$v]]></$k>";
149                                         }
150                                 }
151
152                                 $response .= "</wp_error_data>";
153                         }
154                 } else {
155                         $response = "<response_data><![CDATA[$data]]></response_data>";
156                 }
157
158                 $s = '';
159                 if ( is_array( $r['supplemental'] ) ) {
160                         foreach ( $r['supplemental'] as $k => $v ) {
161                                 $s .= "<$k><![CDATA[$v]]></$k>";
162                         }
163                         $s = "<supplemental>$s</supplemental>";
164                 }
165
166                 if ( false === $action ) {
167                         $action = $_POST['action'];
168                 }
169                 $x = '';
170                 $x .= "<response action='{$action}_$id'>"; // The action attribute in the xml output is formatted like a nonce action
171                 $x .=   "<$what id='$id' " . ( false === $old_id ? '' : "old_id='$old_id' " ) . "position='$position'>";
172                 $x .=           $response;
173                 $x .=           $s;
174                 $x .=   "</$what>";
175                 $x .= "</response>";
176
177                 $this->responses[] = $x;
178                 return $x;
179         }
180
181         /**
182          * Display XML formatted responses.
183          *
184          * Sets the content type header to text/xml.
185          *
186          * @since 2.1.0
187          */
188         public function send() {
189                 header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ) );
190                 echo "<?xml version='1.0' encoding='" . get_option( 'blog_charset' ) . "' standalone='yes'?><wp_ajax>";
191                 foreach ( (array) $this->responses as $response )
192                         echo $response;
193                 echo '</wp_ajax>';
194                 if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
195                         wp_die();
196                 else
197                         die();
198         }
199 }