base_url = $base_url; $this->user = $user; $this->pass = $pass; } public function setSpace($space_id) { $this->space = $space_id; } protected function getClient() { $options = [ 'base_url' => $this->base_url . 'rest/api/', 'defaults' => [ 'auth' => [$this->user, $this->pass] ] ]; return new Client($options); } /** * The standard error message from guzzle is quite poor in informations, * this will give little bit more sense to it and return it * * @param BadResponseException $e * @return BadResponseException */ protected function handleError(BadResponseException $e) { $request = $e->getRequest(); $response = $e->getResponse(); $level = floor($response->getStatusCode() / 100); if ($level == '4') { $label = 'Client error response'; } elseif ($level == '5') { $label = 'Server error response'; } else { $label = 'Unsuccessful response'; } $message = $label . ' [url] ' . $request->getUrl() . ' [status code] ' . $response->getStatusCode() . ' [message] '; try { $message .= $response->json()['message']; } catch (ParseException $e) { $message .= (string) $response->getBody(); } return new BadResponseException($message, $request, $response, $e->getPrevious()); } /** * /rest/api/content/{id}/child/{type} * * @param $rootPage * @return mixed */ public function getList($rootPage) { //We do a limit of 15 as it appears that confluence has //a bug when retrieving more than 20 entries with "body.storage" $url = "content/$rootPage/child/page?expand=version,body.storage&limit=15"; $pages = []; do { try { $list = $this->getClient()->get($url)->json(); } catch (BadResponseException $e) { throw $this->handleError($e); } foreach ($list['results'] as $result) { $pages[$result['title']] = [ "id" => $result['id'], "title" => $result['title'], "version" => $result['version']['number'], "content" => $result['body']['storage']['value'], ]; } if (array_key_exists('next', $list['_links'])) { $url = $list['_links']['next']; } } while (array_key_exists('next', $list['_links'])); return $pages; } /** * /rest/api/content/{id}/child/{type} * * @param $rootPage * @return mixed */ public function getHierarchy($rootPage) { $increment = 15; //We do a limit of 15 as it appears that confluence has //a bug when retrieving more than 20 entries with "body.storage" $base_url = $url = "content/$rootPage/child/page?expand=version,body.storage&limit=$increment"; $start = 0; $children = []; do { try { $hierarchy = $this->getClient()->get($url)->json(); } catch (BadResponseException $e) { throw $this->handleError($e); } foreach ($hierarchy['results'] as $result) { $children[$result['title']] = [ "id" => $result['id'], "title" => $result['title'], "version" => $result['version']['number'], "content" => $result['body']['storage']['value'], "children" => $this->getHierarchy($result['id']) ]; } //We don't use _links->next as after ~30 elements it doesn't show any new elements $start += $increment; $url = "$base_url&start=$start"; } while (!empty($hierarchy['results'])); return $children; } public function createPage($parent_id, $title, $content) { $body = [ 'type' => 'page', 'space' => ['key' => $this->space], 'ancestors' => [['type' => 'page', 'id' => $parent_id]], 'title' => $title, 'body' => ['storage' => ['value' => $content, 'representation' => 'storage']] ]; try { $response = $this->getClient()->post('content', [ 'json' => $body ])->json(); } catch (BadResponseException $e) { throw $this->handleError($e); } return $response['id']; } public function updatePage($parent_id, $page_id, $newVersion, $title, $content) { $body = [ 'type' => 'page', 'space' => ['key' => $this->space], 'ancestors' => [['type' => 'page', 'id' => $parent_id]], 'version' => ['number' => $newVersion, "minorEdit" => false], 'title' => $title, 'body' => ['storage' => ['value' => $content, 'representation' => 'storage']] ]; try { $this->getClient()->put("content/$page_id", ['json' => $body])->json(); } catch (BadResponseException $e) { throw $this->handleError($e); } } public function deletePage($page_id) { try { return $this->getClient()->delete('content/' . $page_id)->json(); } catch (BadResponseException $e) { throw $this->handleError($e); } } public function uploadAttachment($id, $attachment) { //get if attachment is uploaded try { $result = $this->getClient()->get("content/$id/child/attachment?filename=$attachment[filename]")->json(); } catch (BadResponseException $e) { throw $this->handleError($e); } $url = "content/$id/child/attachment" . (count($result['results'])? "/{$result['results'][0]['id']}/data" : ""); try { $this->getClient()->post( $url, [ 'body' => ['file' => fopen($attachment['file']->getPath(), 'r')] , 'headers' => ['X-Atlassian-Token' => 'nocheck'], ] ); } catch (BadResponseException $e) { throw $this->handleError($e); } //FIXME :: When doing an update, Confluence does a null pointer exception } }