File "class-wc-cli-rest-command.php"

Full path: /home/kosmetik/public_html/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-rest-command.php
File size: 10.62 B
MIME-type: text/x-php
Charset: utf-8

Download   Open   Edit   Advanced Editor   Back

<?php

use Automattic\Jetpack\Constants;
use Automattic\WooCommerce\Utilities\NumberUtil;
if (!defined('ABSPATH')) {
    exit;
}
class WC_CLI_REST_Command
{
    protected $routes_with_parent_id = array('customer_download', 'product_review', 'order_note', 'shop_order_refund');
    private $name;
    private $route;
    private $resource_identifier;
    private $schema;
    private $supported_ids = array();
    public function __construct($name, $route, $schema)
    {
        $this->name = $name;
        preg_match_all('#\\([^\\)]+\\)#', $route, $matches);
        $first_match = $matches[0];
        $resource_id = !empty($matches[0]) ? array_pop($matches[0]) : null;
        $this->route = rtrim($route);
        $this->schema = $schema;
        $this->resource_identifier = $resource_id;
        if (in_array($name, $this->routes_with_parent_id, true)) {
            $is_singular = substr($this->route, -strlen($resource_id)) === $resource_id;
            if (!$is_singular) {
                $this->resource_identifier = $first_match[0];
            }
        }
    }
    public function set_supported_ids($supported_ids = array())
    {
        $this->supported_ids = $supported_ids;
    }
    public function get_supported_ids()
    {
        return $this->supported_ids;
    }
    public function create_item($args, $assoc_args)
    {
        $assoc_args = self::decode_json($assoc_args);
        list($status, $body) = $this->do_request('POST', $this->get_filled_route($args), $assoc_args);
        if (\WP_CLI\Utils\get_flag_value($assoc_args, 'porcelain')) {
            WP_CLI::line($body['id']);
        } else {
            WP_CLI::success("Created {$this->name} {$body['id']}.");
        }
    }
    public function delete_item($args, $assoc_args)
    {
        list($status, $body) = $this->do_request('DELETE', $this->get_filled_route($args), $assoc_args);
        $object_id = isset($body['id']) ? $body['id'] : '';
        if (!$object_id && isset($body['slug'])) {
            $object_id = $body['slug'];
        }
        if (\WP_CLI\Utils\get_flag_value($assoc_args, 'porcelain')) {
            WP_CLI::line($object_id);
        } else {
            if (empty($assoc_args['force'])) {
                WP_CLI::success(__('Trashed', 'woocommerce') . " {$this->name} {$object_id}");
            } else {
                WP_CLI::success(__('Deleted', 'woocommerce') . " {$this->name} {$object_id}.");
            }
        }
    }
    public function get_item($args, $assoc_args)
    {
        $route = $this->get_filled_route($args);
        list($status, $body, $headers) = $this->do_request('GET', $route, $assoc_args);
        if (!empty($assoc_args['fields'])) {
            $body = self::limit_item_to_fields($body, $assoc_args['fields']);
        }
        if (empty($assoc_args['format'])) {
            $assoc_args['format'] = 'table';
        }
        if ('headers' === $assoc_args['format']) {
            echo wp_json_encode($headers);
        } elseif ('body' === $assoc_args['format']) {
            echo wp_json_encode($body);
        } elseif ('envelope' === $assoc_args['format']) {
            echo wp_json_encode(array('body' => $body, 'headers' => $headers, 'status' => $status));
        } else {
            $formatter = $this->get_formatter($assoc_args);
            $formatter->display_item($body);
        }
    }
    public function list_items($args, $assoc_args)
    {
        if (!empty($assoc_args['format']) && 'count' === $assoc_args['format']) {
            $method = 'HEAD';
        } else {
            $method = 'GET';
        }
        if (!isset($assoc_args['per_page']) || empty($assoc_args['per_page'])) {
            $assoc_args['per_page'] = '100';
        }
        list($status, $body, $headers) = $this->do_request($method, $this->get_filled_route($args), $assoc_args);
        if (!empty($assoc_args['format']) && 'ids' === $assoc_args['format']) {
            $items = array_column($body, 'id');
        } else {
            $items = $body;
        }
        if (!empty($assoc_args['fields'])) {
            foreach ($items as $key => $item) {
                $items[$key] = self::limit_item_to_fields($item, $assoc_args['fields']);
            }
        }
        if (empty($assoc_args['format'])) {
            $assoc_args['format'] = 'table';
        }
        if (!empty($assoc_args['format']) && 'count' === $assoc_args['format']) {
            echo (int) $headers['X-WP-Total'];
        } elseif ('headers' === $assoc_args['format']) {
            echo wp_json_encode($headers);
        } elseif ('body' === $assoc_args['format']) {
            echo wp_json_encode($body);
        } elseif ('envelope' === $assoc_args['format']) {
            echo wp_json_encode(array('body' => $body, 'headers' => $headers, 'status' => $status, 'api_url' => $this->api_url));
        } else {
            $formatter = $this->get_formatter($assoc_args);
            $formatter->display_items($items);
        }
    }
    public function update_item($args, $assoc_args)
    {
        $assoc_args = self::decode_json($assoc_args);
        list($status, $body) = $this->do_request('POST', $this->get_filled_route($args), $assoc_args);
        if (\WP_CLI\Utils\get_flag_value($assoc_args, 'porcelain')) {
            WP_CLI::line($body['id']);
        } else {
            WP_CLI::success(__('Updated', 'woocommerce') . " {$this->name} {$body['id']}.");
        }
    }
    private function do_request($method, $route, $assoc_args)
    {
        wc_maybe_define_constant('REST_REQUEST', true);
        $request = new WP_REST_Request($method, $route);
        if (in_array($method, array('POST', 'PUT'), true)) {
            $request->set_body_params($assoc_args);
        } else {
            foreach ($assoc_args as $key => $value) {
                $request->set_param($key, $value);
            }
        }
        if (Constants::is_true('SAVEQUERIES')) {
            $original_queries = is_array($GLOBALS['wpdb']->queries) ? array_keys($GLOBALS['wpdb']->queries) : array();
        }
        $response = rest_do_request($request);
        if (Constants::is_true('SAVEQUERIES')) {
            $performed_queries = array();
            foreach ((array) $GLOBALS['wpdb']->queries as $key => $query) {
                if (in_array($key, $original_queries, true)) {
                    continue;
                }
                $performed_queries[] = $query;
            }
            usort($performed_queries, function ($a, $b) {
                if ($a[1] === $b[1]) {
                    return 0;
                }
                return $a[1] > $b[1] ? -1 : 1;
            });
            $query_count = count($performed_queries);
            $query_total_time = 0;
            foreach ($performed_queries as $query) {
                $query_total_time += $query[1];
            }
            $slow_query_message = '';
            if ($performed_queries && 'wc' === WP_CLI::get_config('debug')) {
                $slow_query_message .= '. Ordered by slowness, the queries are:' . PHP_EOL;
                foreach ($performed_queries as $i => $query) {
                    $i++;
                    $bits = explode(', ', $query[2]);
                    $backtrace = implode(', ', array_slice($bits, 13));
                    $seconds = NumberUtil::round($query[1], 6);
                    $slow_query_message .= <<<EOT
{$i}:
- {$seconds} seconds
- {$backtrace}
- {$query[0]}
EOT;
                    $slow_query_message .= PHP_EOL;
                }
            } elseif ('wc' !== WP_CLI::get_config('debug')) {
                $slow_query_message = '. Use --debug=wc to see all queries.';
            }
            $query_total_time = NumberUtil::round($query_total_time, 6);
            WP_CLI::debug("wc command executed {$query_count} queries in {$query_total_time} seconds{$slow_query_message}", 'wc');
        }
        $error = $response->as_error();
        if ($error) {
            if (401 === $response->get_status()) {
                $errors = $error->get_error_messages();
                $errors[] = __('Make sure to include the --user flag with an account that has permissions for this action.', 'woocommerce') . ' {"status":401}';
                $error = implode("\n", $errors);
            }
            WP_CLI::error($error);
        }
        return array($response->get_status(), $response->get_data(), $response->get_headers());
    }
    protected function get_formatter(&$assoc_args)
    {
        if (!empty($assoc_args['fields'])) {
            if (is_string($assoc_args['fields'])) {
                $fields = explode(',', $assoc_args['fields']);
            } else {
                $fields = $assoc_args['fields'];
            }
        } else {
            if (!empty($assoc_args['context'])) {
                $fields = $this->get_context_fields($assoc_args['context']);
            } else {
                $fields = $this->get_context_fields('view');
            }
        }
        return new \WP_CLI\Formatter($assoc_args, $fields);
    }
    private function get_context_fields($context)
    {
        $fields = array();
        foreach ($this->schema['properties'] as $key => $args) {
            if (empty($args['context']) || in_array($context, $args['context'], true)) {
                $fields[] = $key;
            }
        }
        return $fields;
    }
    private function get_filled_route($args = array())
    {
        $supported_id_matched = false;
        $route = $this->route;
        foreach ($this->get_supported_ids() as $id_name => $id_desc) {
            if ('id' !== $id_name && strpos($route, '<' . $id_name . '>') !== false && !empty($args)) {
                $route = str_replace(array('(?P<' . $id_name . '>[\\d]+)', '(?P<' . $id_name . '>\\w[\\w\\s\\-]*)'), $args[0], $route);
                $supported_id_matched = true;
            }
        }
        if (!empty($args)) {
            $id_replacement = $supported_id_matched && !empty($args[1]) ? $args[1] : $args[0];
            $route = str_replace(array('(?P<id>[\\d]+)', '(?P<id>[\\w-]+)'), $id_replacement, $route);
        }
        return rtrim($route);
    }
    private static function limit_item_to_fields($item, $fields)
    {
        if (empty($fields)) {
            return $item;
        }
        if (is_string($fields)) {
            $fields = explode(',', $fields);
        }
        foreach ($item as $i => $field) {
            if (!in_array($i, $fields, true)) {
                unset($item[$i]);
            }
        }
        return $item;
    }
    protected function decode_json($arr)
    {
        foreach ($arr as $key => $value) {
            if ('[' === substr($value, 0, 1) || '{' === substr($value, 0, 1)) {
                $arr[$key] = json_decode($value, true);
            } else {
                continue;
            }
        }
        return $arr;
    }
}