daux.io/libs/Format/Confluence/Api.php

261 lines
7.6 KiB
PHP
Raw Normal View History

<?php namespace Todaymade\Daux\Format\Confluence;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
class Api
{
protected $base_url;
protected $user;
protected $pass;
protected $space;
public function __construct($base_url, $user, $pass)
{
$this->base_url = $base_url;
$this->user = $user;
$this->pass = $pass;
}
public function setSpace($space_id)
{
$this->space = $space_id;
}
2016-04-09 16:42:46 +02:00
/**
* This method is public due to test purposes
* @return Client
*/
public function getClient()
{
$options = [
2016-04-09 16:42:46 +02:00
'base_uri' => $this->base_url . 'rest/api/',
2016-07-27 21:32:51 +02:00
'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
2016-07-29 23:20:01 +02:00
* @return \Exception
*/
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->getUri() .
' [status code] ' . $response->getStatusCode() .
' [message] ';
$body = $response->getBody();
$json = json_decode($body, true);
$message .= ($json != null && array_key_exists('message', $json)) ? $json['message'] : $body;
2016-07-27 21:32:51 +02:00
if ($level == '4' && strpos($message, 'page with this title already exists') !== false) {
2016-01-25 14:47:37 +01:00
return new DuplicateTitleException($message, 0, $e->getPrevious());
}
return new BadResponseException($message, $request, $response, $e->getPrevious());
}
public function getPage($id)
{
2016-07-27 21:32:51 +02:00
$url = "content/$id?expand=ancestors,version,body.storage";
try {
$result = json_decode($this->getClient()->get($url)->getBody(), true);
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
$ancestor_id = null;
if (array_key_exists('ancestors', $result) && count($result['ancestors'])) {
$ancestor_page = end($result['ancestors']); // We need the direct parent
$ancestor_id = $ancestor_page['id'];
}
return [
2016-07-27 21:32:51 +02:00
'id' => $result['id'],
'ancestor_id' => $ancestor_id,
'title' => $result['title'],
'version' => $result['version']['number'],
'content' => $result['body']['storage']['value'],
];
}
2015-05-22 16:15:28 +02:00
/**
2015-07-17 23:38:06 +02:00
* Get a list of pages
2015-05-22 16:15:28 +02:00
*
2016-07-27 21:32:51 +02:00
* @param int $rootPage
2015-07-17 23:38:06 +02:00
* @param bool $recursive
* @return array
2015-05-22 16:15:28 +02:00
*/
2015-07-17 23:38:06 +02:00
public function getList($rootPage, $recursive = false)
2015-05-22 16:15:28 +02:00
{
2015-07-17 23:38:06 +02:00
$increment = 15;
// We set a limit of 15 as it appears that
// Confluence fails silently when retrieving
// more than 20 entries with "body.storage"
$base_url = $url = "content/$rootPage/child/page?expand=version,body.storage&limit=$increment";
$start = 0;
2015-05-22 16:15:28 +02:00
$pages = [];
do {
try {
$hierarchy = json_decode($this->getClient()->get($url)->getBody(), true);
2015-05-22 16:15:28 +02:00
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
2015-07-17 23:38:06 +02:00
foreach ($hierarchy['results'] as $result) {
2015-05-22 16:15:28 +02:00
$pages[$result['title']] = [
2016-07-27 21:32:51 +02:00
'id' => $result['id'],
'title' => $result['title'],
'version' => $result['version']['number'],
'content' => $result['body']['storage']['value'],
2015-05-22 16:15:28 +02:00
];
2015-07-17 23:38:06 +02:00
if ($recursive) {
$pages[$result['title']]['children'] = $this->getList($result['id'], true);
}
2015-05-22 16:15:28 +02:00
}
2015-07-17 23:38:06 +02:00
// We don't use _links->next as after ~30 elements
// it doesn't show any new elements. This seems
// to be a bug in Confluence
$start += $increment;
$url = "$base_url&start=$start";
} while (!empty($hierarchy['results']));
2015-05-22 16:15:28 +02:00
return $pages;
}
/**
2016-07-27 21:32:51 +02:00
* @param int $parent_id
2015-07-17 23:38:06 +02:00
* @param string $title
* @param string $content
2016-07-27 21:32:51 +02:00
* @return int
*/
public function createPage($parent_id, $title, $content)
{
$body = [
'type' => 'page',
'space' => ['key' => $this->space],
'title' => $title,
2016-07-27 21:32:51 +02:00
'body' => ['storage' => ['value' => $content, 'representation' => 'storage']],
];
if ($parent_id) {
$body['ancestors'] = [['type' => 'page', 'id' => $parent_id]];
}
try {
$response = json_decode($this->getClient()->post('content', ['json' => $body])->getBody(), true);
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
return $response['id'];
}
2015-07-17 23:38:06 +02:00
/**
2016-07-27 21:32:51 +02:00
* @param int $parent_id
* @param int $page_id
* @param int $newVersion
2015-07-17 23:38:06 +02:00
* @param string $title
* @param string $content
*/
public function updatePage($parent_id, $page_id, $newVersion, $title, $content)
{
$body = [
'type' => 'page',
'space' => ['key' => $this->space],
2016-07-27 21:32:51 +02:00
'version' => ['number' => $newVersion, 'minorEdit' => true],
'title' => $title,
2016-07-27 21:32:51 +02:00
'body' => ['storage' => ['value' => $content, 'representation' => 'storage']],
];
if ($parent_id) {
$body['ancestors'] = [['type' => 'page', 'id' => $parent_id]];
}
try {
$this->getClient()->put("content/$page_id", ['json' => $body]);
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
}
2015-07-17 23:38:06 +02:00
/**
* Delete a page
*
2016-07-27 21:32:51 +02:00
* @param int $page_id
2015-07-17 23:38:06 +02:00
* @return mixed
*/
public function deletePage($page_id)
{
try {
return json_decode($this->getClient()->delete('content/' . $page_id)->getBody(), true);
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
}
2015-07-17 23:38:06 +02:00
/**
2016-07-27 21:32:51 +02:00
* @param int $id
2015-07-17 23:38:06 +02:00
* @param array $attachment
*/
public function uploadAttachment($id, $attachment)
{
2015-08-02 15:42:23 +02:00
// Check if an attachment with
// this name is uploaded
try {
$url = "content/$id/child/attachment?filename=" . urlencode($attachment['filename']);
$result = json_decode($this->getClient()->get($url)->getBody(), true);
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
2015-08-02 15:42:23 +02:00
$url = "content/$id/child/attachment";
// If the attachment is already uploaded,
// the update URL is different
if (count($result['results'])) {
$url .= "/{$result['results'][0]['id']}/data";
}
$contents = array_key_exists('file', $attachment) ? fopen($attachment['file']->getPath(), 'r') : $attachment['content'];
try {
$this->getClient()->post(
$url,
[
'multipart' => [['name' => 'file', 'contents' => $contents, 'filename' => $attachment['filename']]],
'headers' => ['X-Atlassian-Token' => 'nocheck'],
]
);
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
}
}