1<?php 2/** 3 * Matomo - free/libre analytics platform 4 * 5 * @link https://matomo.org 6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later 7 * 8 */ 9namespace Piwik\Plugins\Marketplace\Api; 10 11use Piwik\Http; 12 13/** 14 * 15 */ 16class Service 17{ 18 const CACHE_TIMEOUT_IN_SECONDS = 1200; 19 const HTTP_REQUEST_TIMEOUT = 60; 20 21 /** 22 * @var string 23 */ 24 private $domain; 25 26 /** 27 * @var null|string 28 */ 29 private $accessToken; 30 31 /** 32 * API version to use on the Marketplace 33 * @var string 34 */ 35 private $version = '2.0'; 36 37 public function __construct($domain) 38 { 39 $this->domain = $domain; 40 } 41 42 public function authenticate($accessToken) 43 { 44 if (empty($accessToken)) { 45 $this->accessToken = null; 46 } elseif (ctype_alnum($accessToken)) { 47 $this->accessToken = $accessToken; 48 } 49 } 50 51 /** 52 * The API version that will be used on the Marketplace. 53 * @return string eg 2.0 54 */ 55 public function getVersion() 56 { 57 return $this->version; 58 } 59 60 /** 61 * Returns the currently set access token 62 * @return null|string 63 */ 64 public function getAccessToken() 65 { 66 return $this->accessToken; 67 } 68 69 public function hasAccessToken() 70 { 71 return !empty($this->accessToken); 72 } 73 74 /** 75 * Downloads data from the given URL via a POST request. If a destination path is given, the downloaded data 76 * will be stored in the given path and returned otherwise. 77 * 78 * Make sure to call {@link authenticate()} to download paid plugins. 79 * 80 * @param string $url An absolute URL to the marketplace including domain. 81 * @param null|string $destinationPath 82 * @param null|int $timeout Defaults to 60 seconds see {@link self::HTTP_REQUEST_METHOD} 83 * @return bool|string Returns the downloaded data or true if a destination path was given. 84 * @throws \Exception 85 */ 86 public function download($url, $destinationPath = null, $timeout = null) 87 { 88 $method = Http::getTransportMethod(); 89 90 if (!isset($timeout)) { 91 $timeout = static::HTTP_REQUEST_TIMEOUT; 92 } 93 94 $post = null; 95 if ($this->accessToken) { 96 $post = array('access_token' => $this->accessToken); 97 } 98 99 $file = Http::ensureDestinationDirectoryExists($destinationPath); 100 101 $response = Http::sendHttpRequestBy($method, 102 $url, 103 $timeout, 104 $userAgent = null, 105 $destinationPath, 106 $file, 107 $followDepth = 0, 108 $acceptLanguage = false, 109 $acceptInvalidSslCertificate = false, 110 $byteRange = false, $getExtendedInfo = false, $httpMethod = 'POST', 111 $httpUsername = null, $httpPassword = null, $post); 112 113 return $response; 114 } 115 116 /** 117 * Executes the given API action on the Marketplace using the given params and returns the result. 118 * 119 * Make sure to call {@link authenticate()} to download paid plugins. 120 * 121 * @param string $action eg 'plugins', 'plugins/$pluginName/info', ... 122 * @param array $params eg array('sort' => 'alpha') 123 * @return mixed 124 * @throws Service\Exception 125 */ 126 public function fetch($action, $params) 127 { 128 $endpoint = sprintf('%s/api/%s/', $this->domain, $this->version); 129 130 $query = Http::buildQuery($params); 131 $url = sprintf('%s%s?%s', $endpoint, $action, $query); 132 133 $response = $this->download($url); 134 135 $result = json_decode($response, true); 136 137 if (is_null($result)) { 138 $message = sprintf('There was an error reading the response from the Marketplace: Please try again later.'); 139 throw new Service\Exception($message, Service\Exception::HTTP_ERROR); 140 } 141 142 if (!empty($result['error'])) { 143 throw new Service\Exception($result['error'], Service\Exception::API_ERROR); 144 } 145 146 return $result; 147 } 148 149 /** 150 * Get the domain that is used in order to access the Marketplace. Eg http://plugins.piwik.org 151 * @return string 152 */ 153 public function getDomain() 154 { 155 return $this->domain; 156 } 157 158} 159