pluginSlug = $config['plugin_slug']; $this->pluginFile = $config['plugin_file']; $this->debugMode = isset($config['debug_mode']) ? $config['debug_mode'] : false; $this->startTime = round(microtime(true) * 1000); $this->proxy = $this->setProxy($config); $this->routes = $routes; // @TODO static Helper $this->Helper = new Helper($this->pluginSlug); $this->Cache = new Cache($this->Helper, $config); $this->Url = new Url(); $this->initOptions($config); $this->Debug = $this->initDebug($this->debugMode); if (isset($config['use']) && in_array('throttle', $config['use'])) { $this->Throttle = new Throttle($this->Helper, $config); } if (isset($config['use']) && in_array('user', $config['use'])) { $this->User = new User($this->Helper, $config); } add_action('rest_api_init', array($this, 'registerRoutes')); add_action('rest_api_init', array($this, 'permalinkRestRouteFix')); // add_action('rest_api_init', function() { // header('Access-Control-Allow-Origin: *'); // }); } public function permalinkRestRouteFix() { global $wp; if (isset($wp->query_vars['rest_route']) && strpos($wp->query_vars['rest_route'], $this->pluginSlug . '/api') !== false) { $split = explode('?q=', $wp->query_vars['rest_route']); if (count($split) === 2) { $wp->query_vars['rest_route'] = $split[0]; $_REQUEST['q'] = $split[1]; } } } public function registerRoutes() { register_rest_route($this->pluginSlug, '/api/', array( 'methods' => 'GET, POST', 'callback' => array($this, 'run'), 'permission_callback' => '__return_true' )); register_rest_route($this->pluginSlug, '/api/(?P[\w-]+)', array( 'methods' => 'GET, POST', 'callback' => array($this, 'run'), 'permission_callback' => '__return_true', 'args' => array( 'endpoint' => array( 'required' => false, 'default' => '', 'enum' => array_keys($this->routes) ) ) )); } public function initDebug($debug_mode) { if (class_exists('\ElfsightYoutubeGalleryApi\Debug')) { return new \ElfsightYoutubeGalleryApi\Debug($this, $debug_mode); } else { return new \ElfsightYoutubeGalleryApi\Core\Debug($this, $debug_mode); } } public function initOptions($config) { if (class_exists('\ElfsightYoutubeGalleryApi\Options')) { return new \ElfsightYoutubeGalleryApi\Options($this->Helper, $config); } else { return new \ElfsightYoutubeGalleryApi\Core\Options($this->Helper, $config); } } public function run(\WP_REST_Request $request) { $endpoint = $request->get_param('endpoint'); $route = isset($this->routes[$endpoint]) ? $this->routes[$endpoint] : null; if (empty($route) || !method_exists($this, $route)) { $this->error(400, self::$ERROR_INVALID_REQUEST, self::$ERROR_INVALID_ROUTE); } return call_user_func(array($this, $route)); } public function request($type, $url, $options = array()) { $type = strtoupper($type); $curl = curl_init(); $request_url = $url; if (!empty($options['query'])) { $request_url .= '?' . http_build_query($options['query']); } $curl_options = array( CURLOPT_URL => $request_url, CURLOPT_HEADER => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_CONNECTTIMEOUT => 60, CURLOPT_TIMEOUT => 60, CURLOPT_FOLLOWLOCATION => !empty($options['follow']) && $options['follow'], CURLOPT_HTTPHEADER => $this->getHeadersList($options), CURLOPT_PROXY => $this->proxy['url'], CURLOPT_PROXYUSERPWD => $this->proxy['credentials'] ); curl_setopt_array($curl, $curl_options); $response = curl_exec($curl); $info = curl_getinfo($curl); $error = curl_error($curl); curl_close($curl); if (isset($options['debug']) && $options['debug']) { return [$response, $info, $error]; } if ($info['http_code'] === 0) { $this->error(400, self::$ERROR_CURL, $error); } return $this->formatResponse($response); } private function getHeadersList($options = array()) { $headers_raw_list = array(); $cookies_raw_list = array(); $cookies = !empty(self::$client['cookies']) ? self::$client['cookies'] : array(); $headers = !empty(self::$client['headers']) ? self::$client['headers'] : array(); if (!empty($options['cookies'])) { $cookies = $this->Helper->arrayMergeAssoc($cookies, $options['cookies']); } if (isset($options['headers'])) { $headers = $this->Helper->arrayMergeAssoc($headers, $options['headers']); } foreach ($cookies as $cookie_name => $cookie_value) { $cookies_raw_list[] = $cookie_name . '=' . $cookie_value; } unset($cookie_name, $cookie_data); $headers['Cookie'] = implode('; ', $cookies_raw_list); foreach ($headers as $header_key => $header_value) { $headers_raw_list[] = $header_key . ': ' . $header_value; } unset($header_key, $header_value); return $headers_raw_list; } public function formatResponse($response) { @list ($response_headers_str, $response_body_encoded, $alt_body_encoded) = explode("\r\n\r\n", $response); if ($alt_body_encoded) { $response_headers_str = $response_body_encoded; $response_body_encoded = $alt_body_encoded; } $response_body = $response_body_encoded; $response_headers_raw_list = explode("\r\n", $response_headers_str); $response_http = array_shift($response_headers_raw_list); preg_match('#^([^\s]+)\s(\d+)\s?([^$]+)?$#', $response_http, $response_http_matches); array_shift($response_http_matches); list ($response_http_protocol, $response_http_code) = $response_http_matches; $response_http_message = ''; if (isset($response_http_matches[2])) { $response_http_message = $response_http_matches[2]; } $response_headers = array(); $response_cookies = array(); foreach ($response_headers_raw_list as $header_row) { list ($header_key, $header_value) = explode(': ', $header_row, 2); if (strtolower($header_key) === 'set-cookie') { $cookie_params = explode('; ', $header_value); if (empty($cookie_params[0])) { continue; } list ($cookie_name, $cookie_value) = explode('=', $cookie_params[0]); $response_cookies[$cookie_name] = $cookie_value; } else { $response_headers[$header_key] = $header_value; } } unset($header_row, $header_key, $header_value, $cookie_name, $cookie_value); if ($response_cookies) { self::$client['cookies'] = $this->Helper->arrayMergeAssoc(self::$client['cookies'] ?: array(), $response_cookies); } return array( 'status' => 1, 'http_protocol' => $response_http_protocol, 'http_code' => (int) $response_http_code, 'http_message' => $response_http_message, 'headers' => $response_headers, 'cookies' => $response_cookies, 'body' => $response_body ); } public function response($data, $options = array()) { if (ob_get_length()) { ob_end_clean(); ob_start(); } $default_options = array( 'encode' => false, 'plain' => false ); $options = !empty($options) ? array_merge($default_options, $options) : $default_options; $callback = $this->input('callback', null, false); $output = $options['encode'] ? json_encode($data) : $data; $content_type = $options['plain'] ? 'text/html' : 'application/json'; if (!empty($callback)) { $callback = htmlspecialchars(strip_tags($callback)); $validate_callback = preg_match('#^jQuery[0-9]*\_[0-9]*$#', $callback); if ($validate_callback) { $output = '/**/ ' . $callback . '(' . $output . ')'; $content_type = 'application/javascript'; } } header('Content-type: ' . $content_type . '; charset=utf-8'); exit($output); } public function error($code = 400, $error_message = null, $additional = '') { if (!$error_message) { $error_message = self::$ERROR_UNKNOWN; } $error = array( 'meta' => array( 'code' => $code, 'error_message' => $error_message ) ); if ($additional) { $additional && $error['meta']['_additional'] = $additional; } $this->response($error, array('encode' => true)); } public function subError($additional) { return $this->error(400, self::$ERROR_UNKNOWN, $additional); } public function input($name, $default = null, $check_empty = true) { $query = array(); if (empty($_REQUEST)) { $parsed_url = parse_url($_SERVER['REQUEST_URI']); if (isset($parsed_url['query'])) { parse_str($parsed_url['query'], $query); } } else { $query = $_REQUEST; } $value = isset($query[$name]) ? $query[$name] : $default; if (empty($value) && $check_empty) { $this->error(400, self::$ERROR_INVALID_REQUEST, $name . ' is not defined'); } return is_string($value) ? urldecode($value) : $value; } private function setProxy($config) { $url = null; $credentials = null; if (isset($config['proxy'])) { $proxy_config = $config['proxy']; if (isset($proxy_config['proxy']) && !empty($proxy_config['proxy'])) { if (!empty($proxy_config['proxy']['server'])) { $url = $proxy_config['proxy']['server']; } if (!empty($proxy_config['proxy']['user']) && !empty($proxy_config['proxy']['password'])) { $credentials = $proxy_config['proxy']['user'] . ':' . $proxy_config['proxy']['password']; } } } return array( 'url' => $url, 'credentials' => $credentials ); } public function checkResponse($response, $checkCode = true) { $hasResponse = !empty($response) && !empty($response['body']) && !empty($response['http_code']); if (!$hasResponse) { return false; } if ($checkCode && (int) $response['http_code'] !== 200) { return false; } return true; } }