PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 3.9.1
WooCommerce v3.9.1
10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / includes / cli / class-wc-cli-rest-command.php
woocommerce / includes / cli Last commit date
class-wc-cli-rest-command.php 8 years ago class-wc-cli-runner.php 8 years ago class-wc-cli-tool-command.php 8 years ago class-wc-cli-update-command.php 7 years ago
class-wc-cli-rest-command.php
459 lines
1 <?php
2 /**
3 * WP_CLI_Rest_Command class file.
4 *
5 * @package WooCommerce\Cli
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Main Command for WooCommere CLI.
14 *
15 * Since a lot of WC operations can be handled via the REST API, we base our CLI
16 * off of Restful to generate commands for each WooCommerce REST API endpoint
17 * so most of the logic is shared.
18 *
19 * Forked from wp-cli/restful (by Daniel Bachhuber, released under the MIT license https://opensource.org/licenses/MIT).
20 * https://github.com/wp-cli/restful
21 *
22 * @version 3.0.0
23 * @package WooCommerce
24 */
25 class WC_CLI_REST_Command {
26 /**
27 * Endpoints that have a parent ID.
28 * Ex: Product reviews, which has a product ID and a review ID.
29 *
30 * @var array
31 */
32 protected $routes_with_parent_id = array(
33 'customer_download',
34 'product_review',
35 'order_note',
36 'shop_order_refund',
37 );
38
39 /**
40 * Name of command/endpoint object.
41 *
42 * @var string
43 */
44 private $name;
45
46 /**
47 * Endpoint route.
48 *
49 * @var string
50 */
51 private $route;
52
53 /**
54 * Main resource ID.
55 *
56 * @var int
57 */
58 private $resource_identifier;
59
60 /**
61 * Schema for command.
62 *
63 * @var array
64 */
65 private $schema;
66
67 /**
68 * List of supported IDs and their description (name => desc).
69 *
70 * @var array
71 */
72 private $supported_ids = array();
73
74 /**
75 * Sets up REST Command.
76 *
77 * @param string $name Name of endpoint object (comes from schema).
78 * @param string $route Path to route of this endpoint.
79 * @param array $schema Schema object.
80 */
81 public function __construct( $name, $route, $schema ) {
82 $this->name = $name;
83
84 preg_match_all( '#\([^\)]+\)#', $route, $matches );
85 $first_match = $matches[0];
86 $resource_id = ! empty( $matches[0] ) ? array_pop( $matches[0] ) : null;
87 $this->route = rtrim( $route );
88 $this->schema = $schema;
89
90 $this->resource_identifier = $resource_id;
91 if ( in_array( $name, $this->routes_with_parent_id, true ) ) {
92 $is_singular = substr( $this->route, - strlen( $resource_id ) ) === $resource_id;
93 if ( ! $is_singular ) {
94 $this->resource_identifier = $first_match[0];
95 }
96 }
97 }
98
99 /**
100 * Passes supported ID arguments (things like product_id, order_id, etc) that we should look for in addition to id.
101 *
102 * @param array $supported_ids List of supported IDs.
103 */
104 public function set_supported_ids( $supported_ids = array() ) {
105 $this->supported_ids = $supported_ids;
106 }
107
108 /**
109 * Returns an ID of supported ID arguments (things like product_id, order_id, etc) that we should look for in addition to id.
110 *
111 * @return array
112 */
113 public function get_supported_ids() {
114 return $this->supported_ids;
115 }
116
117 /**
118 * Create a new item.
119 *
120 * @subcommand create
121 *
122 * @param array $args WP-CLI positional arguments.
123 * @param array $assoc_args WP-CLI associative arguments.
124 */
125 public function create_item( $args, $assoc_args ) {
126 $assoc_args = self::decode_json( $assoc_args );
127 list( $status, $body ) = $this->do_request( 'POST', $this->get_filled_route( $args ), $assoc_args );
128 if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) {
129 WP_CLI::line( $body['id'] );
130 } else {
131 WP_CLI::success( "Created {$this->name} {$body['id']}." );
132 }
133 }
134
135 /**
136 * Delete an existing item.
137 *
138 * @subcommand delete
139 *
140 * @param array $args WP-CLI positional arguments.
141 * @param array $assoc_args WP-CLI associative arguments.
142 */
143 public function delete_item( $args, $assoc_args ) {
144 list( $status, $body ) = $this->do_request( 'DELETE', $this->get_filled_route( $args ), $assoc_args );
145 if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) {
146 WP_CLI::line( $body['id'] );
147 } else {
148 if ( empty( $assoc_args['force'] ) ) {
149 WP_CLI::success( __( 'Trashed', 'woocommerce' ) . " {$this->name} {$body['id']}" );
150 } else {
151 WP_CLI::success( __( 'Deleted', 'woocommerce' ) . " {$this->name} {$body['id']}." );
152 }
153 }
154 }
155
156 /**
157 * Get a single item.
158 *
159 * @subcommand get
160 *
161 * @param array $args WP-CLI positional arguments.
162 * @param array $assoc_args WP-CLI associative arguments.
163 */
164 public function get_item( $args, $assoc_args ) {
165 $route = $this->get_filled_route( $args );
166 list( $status, $body, $headers ) = $this->do_request( 'GET', $route, $assoc_args );
167
168 if ( ! empty( $assoc_args['fields'] ) ) {
169 $body = self::limit_item_to_fields( $body, $assoc_args['fields'] );
170 }
171
172 if ( empty( $assoc_args['format'] ) ) {
173 $assoc_args['format'] = 'table';
174 }
175
176 if ( 'headers' === $assoc_args['format'] ) {
177 echo wp_json_encode( $headers );
178 } elseif ( 'body' === $assoc_args['format'] ) {
179 echo wp_json_encode( $body );
180 } elseif ( 'envelope' === $assoc_args['format'] ) {
181 echo wp_json_encode(
182 array(
183 'body' => $body,
184 'headers' => $headers,
185 'status' => $status,
186 )
187 );
188 } else {
189 $formatter = $this->get_formatter( $assoc_args );
190 $formatter->display_item( $body );
191 }
192 }
193
194 /**
195 * List all items.
196 *
197 * @subcommand list
198 *
199 * @param array $args WP-CLI positional arguments.
200 * @param array $assoc_args WP-CLI associative arguments.
201 */
202 public function list_items( $args, $assoc_args ) {
203 if ( ! empty( $assoc_args['format'] ) && 'count' === $assoc_args['format'] ) {
204 $method = 'HEAD';
205 } else {
206 $method = 'GET';
207 }
208
209 if ( ! isset( $assoc_args['per_page'] ) || empty( $assoc_args['per_page'] ) ) {
210 $assoc_args['per_page'] = '100';
211 }
212
213 list( $status, $body, $headers ) = $this->do_request( $method, $this->get_filled_route( $args ), $assoc_args );
214 if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) {
215 $items = array_column( $body, 'id' );
216 } else {
217 $items = $body;
218 }
219
220 if ( ! empty( $assoc_args['fields'] ) ) {
221 foreach ( $items as $key => $item ) {
222 $items[ $key ] = self::limit_item_to_fields( $item, $assoc_args['fields'] );
223 }
224 }
225
226 if ( empty( $assoc_args['format'] ) ) {
227 $assoc_args['format'] = 'table';
228 }
229
230 if ( ! empty( $assoc_args['format'] ) && 'count' === $assoc_args['format'] ) {
231 echo (int) $headers['X-WP-Total'];
232 } elseif ( 'headers' === $assoc_args['format'] ) {
233 echo wp_json_encode( $headers );
234 } elseif ( 'body' === $assoc_args['format'] ) {
235 echo wp_json_encode( $body );
236 } elseif ( 'envelope' === $assoc_args['format'] ) {
237 echo wp_json_encode(
238 array(
239 'body' => $body,
240 'headers' => $headers,
241 'status' => $status,
242 'api_url' => $this->api_url,
243 )
244 );
245 } else {
246 $formatter = $this->get_formatter( $assoc_args );
247 $formatter->display_items( $items );
248 }
249 }
250
251 /**
252 * Update an existing item.
253 *
254 * @subcommand update
255 *
256 * @param array $args WP-CLI positional arguments.
257 * @param array $assoc_args WP-CLI associative arguments.
258 */
259 public function update_item( $args, $assoc_args ) {
260 $assoc_args = self::decode_json( $assoc_args );
261 list( $status, $body ) = $this->do_request( 'POST', $this->get_filled_route( $args ), $assoc_args );
262 if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) {
263 WP_CLI::line( $body['id'] );
264 } else {
265 WP_CLI::success( __( 'Updated', 'woocommerce' ) . " {$this->name} {$body['id']}." );
266 }
267 }
268
269 /**
270 * Do a REST Request
271 *
272 * @param string $method Request method. Examples: 'POST', 'PUT', 'DELETE' or 'GET'.
273 * @param string $route Resource route.
274 * @param array $assoc_args Associative arguments passed to the originating WP-CLI command.
275 *
276 * @return array
277 */
278 private function do_request( $method, $route, $assoc_args ) {
279 wc_maybe_define_constant( 'REST_REQUEST', true );
280
281 $request = new WP_REST_Request( $method, $route );
282 if ( in_array( $method, array( 'POST', 'PUT' ), true ) ) {
283 $request->set_body_params( $assoc_args );
284 } else {
285 foreach ( $assoc_args as $key => $value ) {
286 $request->set_param( $key, $value );
287 }
288 }
289 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
290 $original_queries = is_array( $GLOBALS['wpdb']->queries ) ? array_keys( $GLOBALS['wpdb']->queries ) : array();
291 }
292 $response = rest_do_request( $request );
293 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
294 $performed_queries = array();
295 foreach ( (array) $GLOBALS['wpdb']->queries as $key => $query ) {
296 if ( in_array( $key, $original_queries, true ) ) {
297 continue;
298 }
299 $performed_queries[] = $query;
300 }
301 usort(
302 $performed_queries, function( $a, $b ) {
303 if ( $a[1] === $b[1] ) {
304 return 0;
305 }
306 return ( $a[1] > $b[1] ) ? -1 : 1;
307 }
308 );
309
310 $query_count = count( $performed_queries );
311 $query_total_time = 0;
312 foreach ( $performed_queries as $query ) {
313 $query_total_time += $query[1];
314 }
315 $slow_query_message = '';
316 if ( $performed_queries && 'wc' === WP_CLI::get_config( 'debug' ) ) {
317 $slow_query_message .= '. Ordered by slowness, the queries are:' . PHP_EOL;
318 foreach ( $performed_queries as $i => $query ) {
319 $i++;
320 $bits = explode( ', ', $query[2] );
321 $backtrace = implode( ', ', array_slice( $bits, 13 ) );
322 $seconds = round( $query[1], 6 );
323 $slow_query_message .= <<<EOT
324 {$i}:
325 - {$seconds} seconds
326 - {$backtrace}
327 - {$query[0]}
328 EOT;
329 $slow_query_message .= PHP_EOL;
330 }
331 } elseif ( 'wc' !== WP_CLI::get_config( 'debug' ) ) {
332 $slow_query_message = '. Use --debug=wc to see all queries.';
333 }
334 $query_total_time = round( $query_total_time, 6 );
335 WP_CLI::debug( "wc command executed {$query_count} queries in {$query_total_time} seconds{$slow_query_message}", 'wc' );
336 }
337
338 $error = $response->as_error();
339
340 if ( $error ) {
341 // For authentication errors (status 401), include a reminder to set the --user flag.
342 // WP_CLI::error will only return the first message from WP_Error, so we will pass a string containing both instead.
343 if ( 401 === $response->get_status() ) {
344 $errors = $error->get_error_messages();
345 $errors[] = __( 'Make sure to include the --user flag with an account that has permissions for this action.', 'woocommerce' ) . ' {"status":401}';
346 $error = implode( "\n", $errors );
347 }
348 WP_CLI::error( $error );
349 }
350 return array( $response->get_status(), $response->get_data(), $response->get_headers() );
351 }
352
353 /**
354 * Get Formatter object based on supplied parameters.
355 *
356 * @param array $assoc_args Parameters passed to command. Determines formatting.
357 * @return \WP_CLI\Formatter
358 */
359 protected function get_formatter( &$assoc_args ) {
360 if ( ! empty( $assoc_args['fields'] ) ) {
361 if ( is_string( $assoc_args['fields'] ) ) {
362 $fields = explode( ',', $assoc_args['fields'] );
363 } else {
364 $fields = $assoc_args['fields'];
365 }
366 } else {
367 if ( ! empty( $assoc_args['context'] ) ) {
368 $fields = $this->get_context_fields( $assoc_args['context'] );
369 } else {
370 $fields = $this->get_context_fields( 'view' );
371 }
372 }
373 return new \WP_CLI\Formatter( $assoc_args, $fields );
374 }
375
376 /**
377 * Get a list of fields present in a given context
378 *
379 * @param string $context Scope under which the request is made. Determines fields present in response.
380 * @return array
381 */
382 private function get_context_fields( $context ) {
383 $fields = array();
384 foreach ( $this->schema['properties'] as $key => $args ) {
385 if ( empty( $args['context'] ) || in_array( $context, $args['context'], true ) ) {
386 $fields[] = $key;
387 }
388 }
389 return $fields;
390 }
391
392 /**
393 * Get the route for this resource
394 *
395 * @param array $args Positional arguments passed to the originating WP-CLI command.
396 * @return string
397 */
398 private function get_filled_route( $args = array() ) {
399 $supported_id_matched = false;
400 $route = $this->route;
401
402 foreach ( $this->get_supported_ids() as $id_name => $id_desc ) {
403 if ( 'id' !== $id_name && strpos( $route, '<' . $id_name . '>' ) !== false && ! empty( $args ) ) {
404 $route = str_replace( '(?P<' . $id_name . '>[\d]+)', $args[0], $route );
405 $supported_id_matched = true;
406 }
407 }
408
409 if ( ! empty( $args ) ) {
410 $id_replacement = $supported_id_matched && ! empty( $args[1] ) ? $args[1] : $args[0];
411 $route = str_replace( array( '(?P<id>[\d]+)', '(?P<id>[\w-]+)' ), $id_replacement, $route );
412 }
413
414 return rtrim( $route );
415 }
416
417 /**
418 * Reduce an item to specific fields.
419 *
420 * @param array $item Item to reduce.
421 * @param array $fields Fields to keep.
422 * @return array
423 */
424 private static function limit_item_to_fields( $item, $fields ) {
425 if ( empty( $fields ) ) {
426 return $item;
427 }
428 if ( is_string( $fields ) ) {
429 $fields = explode( ',', $fields );
430 }
431 foreach ( $item as $i => $field ) {
432 if ( ! in_array( $i, $fields, true ) ) {
433 unset( $item[ $i ] );
434 }
435 }
436 return $item;
437 }
438
439 /**
440 * JSON can be passed in some more complicated objects, like the payment gateway settings array.
441 * This function decodes the json (if present) and tries to get it's value.
442 *
443 * @param array $arr Array that will be scanned for JSON encoded values.
444 *
445 * @return array
446 */
447 protected function decode_json( $arr ) {
448 foreach ( $arr as $key => $value ) {
449 if ( '[' === substr( $value, 0, 1 ) || '{' === substr( $value, 0, 1 ) ) {
450 $arr[ $key ] = json_decode( $value, true );
451 } else {
452 continue;
453 }
454 }
455 return $arr;
456 }
457
458 }
459