Wordpress 4.6
[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          */
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 ( defined( 'DOING_AJAX' ) && DOING_AJAX )
153                         wp_die();
154                 else
155                         die();
156         }
157 }