10 protected $sendAsJson = false;
11 protected $directUpload = false;
12 protected $uploadsInfo = [];
13 protected $dedicatedBody = false;
15 protected $properties = [];
16 protected $type = null;
17 protected $action = null;
18 protected $url = null;
20 public function __construct($host, $cfg)
24 $this->req = $this->getHttpRequest(
25 $this->host->endpoints->micropub, $this->host->token
29 protected function getHttpRequest($url, $accessToken)
31 $req = new MyHttpRequest2($url, 'POST');
32 $req->setHeader('User-Agent: shpub');
33 if (version_compare(PHP_VERSION, '5.6.0', '<')) {
34 //correct ssl validation on php 5.5 is a pain, so disable
35 $req->setConfig('ssl_verify_host', false);
36 $req->setConfig('ssl_verify_peer', false);
38 $req->setHeader('Content-type', 'application/x-www-form-urlencoded');
39 $req->setHeader('authorization', 'Bearer ' . $accessToken);
43 public function send($body = null)
45 if ($this->sendAsJson) {
48 throw new \Exception('body already defined');
50 $this->req->setHeader('Content-Type: application/json');
52 if ($this->action !== null) {
53 $data['action'] = $this->action;
55 if ($this->url !== null) {
56 $data['url'] = $this->url;
58 if ($this->type !== null) {
59 $data['type'] = array('h-' . $this->type);
61 if (count($this->properties)) {
62 $data['properties'] = $this->properties;
64 $body = json_encode($data);
67 if ($this->type !== null) {
68 $this->req->addPostParameter('h', $this->type);
70 if ($this->action !== null) {
71 $this->req->addPostParameter('action', $this->action);
73 if ($this->url !== null) {
74 $this->req->addPostParameter('url', $this->url);
76 foreach ($this->properties as $propkey => $propval) {
77 if (isset($propval['html'])) {
78 //workaround for content[html]
79 $propkey = $propkey . '[html]';
80 $propval = $propval['html'];
81 } else if (count($propval) == 1) {
82 $propval = reset($propval);
84 $this->req->addPostParameter($propkey, $propval);
89 $this->dedicatedBody = true;
90 $this->req->setBody($body);
92 if ($this->cfg->debug) {
93 $cp = new CurlPrinter();
94 $cp->show($this->req, $this->uploadsInfo, $this->dedicatedBody);
97 if ($this->cfg->dryRun && $this->req->getMethod() != 'GET') {
98 //do not run any modifying queries
99 //fake a successful response
100 $res = new \HTTP_Request2_Response('HTTP/1.1 200 OK', false);
101 $res->parseHeaderLine('Content-type: text/plain');
102 $res->appendBody('Fake --dry-run response');
106 $res = $this->req->send();
108 if (intval($res->getStatus() / 100) != 2) {
109 $this->displayErrorResponse($res);
114 protected function displayErrorResponse($res)
117 'Server returned an error status code ' . $res->getStatus()
121 if (Util::getMimeType($res) == 'application/json') {
122 $errData = json_decode($res->getBody());
123 if (!isset($errData->error)) {
124 Log::err('Error response does not contain "error" property');
125 } else if (isset($errData->error_description)) {
126 Log::err($errData->error . ': ' . $errData->error_description);
129 Log::err($errData->error);
135 Log::err($res->getBody());
140 public function setAction($action)
142 $this->action = $action;
145 public function setType($type)
150 public function setUrl($url)
158 * @param string $fieldName name of file-upload field
159 * @param array $fileNames list of local file paths
163 public function addUpload($fieldName, $fileNames)
165 if ($this->directUpload && $this->sendAsJson) {
166 throw new \Exception(
167 'Cannot do direct upload with JSON requests'
171 if ($this->host->endpoints->media === null
172 || $this->directUpload
174 if ($this->sendAsJson) {
175 throw new \Exception(
176 'No media endpoint available, which is required for JSON'
179 if (count($fileNames) == 1) {
180 $fileNames = reset($fileNames);
182 $this->uploadsInfo[$fieldName] = $fileNames;
183 return $this->req->addUpload($fieldName, $fileNames);
187 foreach ($fileNames as $fileName) {
188 $urls[] = $this->uploadToMediaEndpoint($fileName);
190 if (count($urls) == 1) {
191 $urls = reset($urls);
193 $this->addProperty($fieldName, $urls);
197 * Execute the file upload
199 * @param string $fileName File path
201 * @return string URL at media endpoint
203 public function uploadToMediaEndpoint($fileName)
205 $httpReq = $this->getHttpRequest(
206 $this->host->endpoints->media, $this->host->token
208 $httpReq->addUpload('file', $fileName);
210 if ($this->cfg->debug) {
211 $cp = new CurlPrinter();
212 $cp->show($httpReq, ['file' => $fileName]);
214 $res = $httpReq->send();
215 if (intval($res->getStatus() / 100) != 2) {
217 'Media endpoint returned an error status code '
220 Log::err($res->getBody());
224 $location = $res->getHeader('location');
225 if ($location === null) {
226 Log::err('Media endpoint did not return a URL');
230 $base = new \Net_URL2($this->host->endpoints->media);
231 return (string) $base->resolve($location);
234 public function addContent($text, $isHtml)
238 'content', [['html' => $text]]
241 $this->addProperty('content', $text);
247 * Adds a micropub property to the request.
249 * @param string $key Parameter name
250 * @param string|array $values One or multiple values
254 public function addProperty($key, $values)
256 $this->properties[$key] = (array) $values;
259 public function setSendAsJson($json)
261 $this->sendAsJson = $json;
264 public function setDirectUpload($directUpload)
266 $this->directUpload = $directUpload;