Create New Item
×
Item Type
File
Folder
Item Name
×
Search file in folder and subfolders...
File Manager
/
wp-content
/
plugins
/
woocommerce
/
includes
/
legacy
/
api
/
v3
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php if (!defined('ABSPATH')) { exit; } require_once ABSPATH . 'wp-admin/includes/admin.php'; class WC_API_Server { const METHOD_GET = 1; const METHOD_POST = 2; const METHOD_PUT = 4; const METHOD_PATCH = 8; const METHOD_DELETE = 16; const READABLE = 1; const CREATABLE = 2; const EDITABLE = 14; const DELETABLE = 16; const ALLMETHODS = 31; const ACCEPT_RAW_DATA = 64; const ACCEPT_DATA = 128; const HIDDEN_ENDPOINT = 256; public static $method_map = array('HEAD' => self::METHOD_GET, 'GET' => self::METHOD_GET, 'POST' => self::METHOD_POST, 'PUT' => self::METHOD_PUT, 'PATCH' => self::METHOD_PATCH, 'DELETE' => self::METHOD_DELETE); public $path = ''; public $method = 'HEAD'; public $params = array('GET' => array(), 'POST' => array()); public $headers = array(); public $files = array(); public $handler; public function __construct($path) { if (empty($path)) { if (isset($_SERVER['PATH_INFO'])) { $path = $_SERVER['PATH_INFO']; } else { $path = '/'; } } $this->path = $path; $this->method = $_SERVER['REQUEST_METHOD']; $this->params['GET'] = $_GET; $this->params['POST'] = $_POST; $this->headers = $this->get_headers($_SERVER); $this->files = $_FILES; if (isset($_GET['_method'])) { $this->method = strtoupper($_GET['_method']); } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { $this->method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']; } $handler_class = apply_filters('woocommerce_api_default_response_handler', 'WC_API_JSON_Handler', $this->path, $this); $this->handler = new $handler_class(); } public function check_authentication() { $user = apply_filters('woocommerce_api_check_authentication', null, $this); if (is_a($user, 'WP_User')) { wp_set_current_user($user->ID); } elseif (!is_wp_error($user)) { $user = new WP_Error('woocommerce_api_authentication_error', __('Invalid authentication method', 'woocommerce'), array('code' => 500)); } return $user; } protected function error_to_array($error) { $errors = array(); foreach ((array) $error->errors as $code => $messages) { foreach ((array) $messages as $message) { $errors[] = array('code' => $code, 'message' => $message); } } return array('errors' => $errors); } public function serve_request() { do_action('woocommerce_api_server_before_serve', $this); $this->header('Content-Type', $this->handler->get_content_type(), true); if (!apply_filters('woocommerce_api_enabled', true, $this) || 'no' === get_option('woocommerce_api_enabled')) { $this->send_status(404); echo $this->handler->generate_response(array('errors' => array('code' => 'woocommerce_api_disabled', 'message' => 'The WooCommerce API is disabled on this site'))); return; } $result = $this->check_authentication(); if (!is_wp_error($result)) { $result = $this->dispatch(); } if (is_wp_error($result)) { $data = $result->get_error_data(); if (is_array($data) && isset($data['status'])) { $this->send_status($data['status']); } $result = $this->error_to_array($result); } $served = apply_filters('woocommerce_api_serve_request', false, $result, $this); if (!$served) { if ('HEAD' === $this->method) { return; } echo $this->handler->generate_response($result); } } public function get_routes() { $endpoints = array('/' => array(array($this, 'get_index'), self::READABLE)); $endpoints = apply_filters('woocommerce_api_endpoints', $endpoints); foreach ($endpoints as $route => &$handlers) { if (count($handlers) <= 2 && isset($handlers[1]) && !is_array($handlers[1])) { $handlers = array($handlers); } } return $endpoints; } public function dispatch() { switch ($this->method) { case 'HEAD': case 'GET': $method = self::METHOD_GET; break; case 'POST': $method = self::METHOD_POST; break; case 'PUT': $method = self::METHOD_PUT; break; case 'PATCH': $method = self::METHOD_PATCH; break; case 'DELETE': $method = self::METHOD_DELETE; break; default: return new WP_Error('woocommerce_api_unsupported_method', __('Unsupported request method', 'woocommerce'), array('status' => 400)); } foreach ($this->get_routes() as $route => $handlers) { foreach ($handlers as $handler) { $callback = $handler[0]; $supported = isset($handler[1]) ? $handler[1] : self::METHOD_GET; if (!($supported & $method)) { continue; } $match = preg_match('@^' . $route . '$@i', urldecode($this->path), $args); if (!$match) { continue; } if (!is_callable($callback)) { return new WP_Error('woocommerce_api_invalid_handler', __('The handler for the route is invalid', 'woocommerce'), array('status' => 500)); } $args = array_merge($args, $this->params['GET']); if ($method & self::METHOD_POST) { $args = array_merge($args, $this->params['POST']); } if ($supported & self::ACCEPT_DATA) { $data = $this->handler->parse_body($this->get_raw_data()); $args = array_merge($args, array('data' => $data)); } elseif ($supported & self::ACCEPT_RAW_DATA) { $data = $this->get_raw_data(); $args = array_merge($args, array('data' => $data)); } $args['_method'] = $method; $args['_route'] = $route; $args['_path'] = $this->path; $args['_headers'] = $this->headers; $args['_files'] = $this->files; $args = apply_filters('woocommerce_api_dispatch_args', $args, $callback); if (is_wp_error($args)) { return $args; } $params = $this->sort_callback_params($callback, $args); if (is_wp_error($params)) { return $params; } return call_user_func_array($callback, $params); } } return new WP_Error('woocommerce_api_no_route', __('No route was found matching the URL and request method', 'woocommerce'), array('status' => 404)); } protected function urldecode_deep($value) { if (is_array($value)) { return array_map(array($this, 'urldecode_deep'), $value); } else { return urldecode($value); } } protected function sort_callback_params($callback, $provided) { if (is_array($callback)) { $ref_func = new ReflectionMethod($callback[0], $callback[1]); } else { $ref_func = new ReflectionFunction($callback); } $wanted = $ref_func->getParameters(); $ordered_parameters = array(); foreach ($wanted as $param) { if (isset($provided[$param->getName()])) { if ('data' == $param->getName()) { $ordered_parameters[] = $provided[$param->getName()]; continue; } $ordered_parameters[] = $this->urldecode_deep($provided[$param->getName()]); } elseif ($param->isDefaultValueAvailable()) { $ordered_parameters[] = $param->getDefaultValue(); } else { return new WP_Error('woocommerce_api_missing_callback_param', sprintf(__('Missing parameter %s', 'woocommerce'), $param->getName()), array('status' => 400)); } } return $ordered_parameters; } public function get_index() { $available = array('store' => array('name' => get_option('blogname'), 'description' => get_option('blogdescription'), 'URL' => get_option('siteurl'), 'wc_version' => WC()->version, 'version' => WC_API::VERSION, 'routes' => array(), 'meta' => array('timezone' => wc_timezone_string(), 'currency' => get_woocommerce_currency(), 'currency_format' => get_woocommerce_currency_symbol(), 'currency_position' => get_option('woocommerce_currency_pos'), 'thousand_separator' => get_option('woocommerce_price_thousand_sep'), 'decimal_separator' => get_option('woocommerce_price_decimal_sep'), 'price_num_decimals' => wc_get_price_decimals(), 'tax_included' => wc_prices_include_tax(), 'weight_unit' => get_option('woocommerce_weight_unit'), 'dimension_unit' => get_option('woocommerce_dimension_unit'), 'ssl_enabled' => 'yes' === get_option('woocommerce_force_ssl_checkout') || wc_site_is_https(), 'permalinks_enabled' => '' !== get_option('permalink_structure'), 'generate_password' => 'yes' === get_option('woocommerce_registration_generate_password'), 'links' => array('help' => 'https://woocommerce.github.io/woocommerce-rest-api-docs/')))); foreach ($this->get_routes() as $route => $callbacks) { $data = array(); $route = preg_replace('#\\(\\?P(<\\w+?>).*?\\)#', '$1', $route); foreach (self::$method_map as $name => $bitmask) { foreach ($callbacks as $callback) { if ($callback[1] & self::HIDDEN_ENDPOINT) { continue 3; } if ($callback[1] & $bitmask) { $data['supports'][] = $name; } if ($callback[1] & self::ACCEPT_DATA) { $data['accepts_data'] = true; } if (strpos($route, '<') === false) { $data['meta'] = array('self' => get_woocommerce_api_url($route)); } } } $available['store']['routes'][$route] = apply_filters('woocommerce_api_endpoints_description', $data); } return apply_filters('woocommerce_api_index', $available); } public function send_status($code) { status_header($code); } public function header($key, $value, $replace = true) { header(sprintf('%s: %s', $key, $value), $replace); } public function link_header($rel, $link, $other = array()) { $header = sprintf('<%s>; rel="%s"', $link, esc_attr($rel)); foreach ($other as $key => $value) { if ('title' == $key) { $value = '"' . $value . '"'; } $header .= '; ' . $key . '=' . $value; } $this->header('Link', $header, false); } public function add_pagination_headers($query) { if (is_a($query, 'WP_User_Query')) { $single = count($query->get_results()) == 1; $total = $query->get_total(); if ($query->get('number') > 0) { $page = $query->get('offset') / $query->get('number') + 1; $total_pages = ceil($total / $query->get('number')); } else { $page = 1; $total_pages = 1; } } elseif (is_a($query, 'stdClass')) { $page = $query->page; $single = $query->is_single; $total = $query->total; $total_pages = $query->total_pages; } else { $page = $query->get('paged'); $single = $query->is_single(); $total = $query->found_posts; $total_pages = $query->max_num_pages; } if (!$page) { $page = 1; } $next_page = absint($page) + 1; if (!$single) { if ($page > 1) { $this->link_header('first', $this->get_paginated_url(1)); $this->link_header('prev', $this->get_paginated_url($page - 1)); } if ($next_page <= $total_pages) { $this->link_header('next', $this->get_paginated_url($next_page)); } if ($page != $total_pages) { $this->link_header('last', $this->get_paginated_url($total_pages)); } } $this->header('X-WC-Total', $total); $this->header('X-WC-TotalPages', $total_pages); do_action('woocommerce_api_pagination_headers', $this, $query); } private function get_paginated_url($page) { $request = remove_query_arg('page'); $request = urldecode(add_query_arg('page', $page, $request)); $host = parse_url(get_home_url(), PHP_URL_HOST); return set_url_scheme("http://{$host}{$request}"); } public function get_raw_data() { if (function_exists('phpversion') && version_compare(phpversion(), '5.6', '>=')) { return file_get_contents('php://input'); } global $HTTP_RAW_POST_DATA; if (!isset($HTTP_RAW_POST_DATA)) { $HTTP_RAW_POST_DATA = file_get_contents('php://input'); } return $HTTP_RAW_POST_DATA; } public function parse_datetime($datetime) { if (strpos($datetime, '.') !== false) { $datetime = preg_replace('/\\.\\d+/', '', $datetime); } $datetime = preg_replace('/[+-]\\d+:+\\d+$/', '+00:00', $datetime); try { $datetime = new DateTime($datetime, new DateTimeZone('UTC')); } catch (Exception $e) { $datetime = new DateTime('@0'); } return $datetime->format('Y-m-d H:i:s'); } public function format_datetime($timestamp, $convert_to_utc = false, $convert_to_gmt = false) { if ($convert_to_gmt) { if (is_numeric($timestamp)) { $timestamp = date('Y-m-d H:i:s', $timestamp); } $timestamp = get_gmt_from_date($timestamp); } if ($convert_to_utc) { $timezone = new DateTimeZone(wc_timezone_string()); } else { $timezone = new DateTimeZone('UTC'); } try { if (is_numeric($timestamp)) { $date = new DateTime("@{$timestamp}"); } else { $date = new DateTime($timestamp, $timezone); } if ($convert_to_utc) { $date->modify(-1 * $date->getOffset() . ' seconds'); } } catch (Exception $e) { $date = new DateTime('@0'); } return $date->format('Y-m-d\\TH:i:s\\Z'); } public function get_headers($server) { $headers = array(); $additional = array('CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true); foreach ($server as $key => $value) { if (strpos($key, 'HTTP_') === 0) { $headers[substr($key, 5)] = $value; } elseif (isset($additional[$key])) { $headers[$key] = $value; } } return $headers; } }