use Friendica\Model\Profile;
use Friendica\Model\User;
use Friendica\Model\Verb;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException;
use Friendica\Network\HTTPException\BadRequestException;
Logger::warning(API_LOG_PREFIX . 'not implemented', ['module' => 'api', 'action' => 'call', 'query' => DI::args()->getQueryString()]);
throw new NotFoundException();
} catch (HTTPException $e) {
- BaseApi::error($e->getCode(), $e->getDescription(), $e->getMessage(), $type);
+ ApiResponse::error($e->getCode(), $e->getDescription(), $e->getMessage(), $type);
}
}
if (!empty(DI::args()->getArgv()[$argid])) {
$data = explode(".", DI::args()->getArgv()[$argid]);
if (count($data) > 1) {
- list($user, $null) = $data;
+ [$user, $null] = $data;
}
}
if (is_numeric($user)) {
unset($user_info["uid"]);
unset($user_info["self"]);
- return BaseApi::formatData("user", $type, ['user' => $user_info]);
+ return ApiResponse::formatData("user", $type, ['user' => $user_info]);
}
/// @TODO move to top of file or somewhere better
Logger::info(API_LOG_PREFIX . 'End', ['action' => 'get_status', 'status_info' => $status_info]);
- return BaseApi::formatData('statuses', $type, ['status' => $status_info]);
+ return ApiResponse::formatData('statuses', $type, ['status' => $status_info]);
}
/**
unset($user_info['uid']);
unset($user_info['self']);
- return BaseApi::formatData('user', $type, ['user' => $user_info]);
+ return ApiResponse::formatData('user', $type, ['user' => $user_info]);
}
/// @TODO move to top of file or somewhere better
throw new BadRequestException('No search term specified.');
}
- return BaseApi::formatData('users', $type, $userlist);
+ return ApiResponse::formatData('users', $type, $userlist);
}
/// @TODO move to top of file or somewhere better
throw new NotFoundException;
}
- return BaseApi::formatData("users", $type, ['users' => $users]);
+ return ApiResponse::formatData("users", $type, ['users' => $users]);
}
/// @TODO move to top of file or somewhere better
DBA::close($tags);
if (empty($uriids)) {
- return BaseApi::formatData('statuses', $type, $data);
+ return ApiResponse::formatData('statuses', $type, $data);
}
$condition = ['uri-id' => $uriids];
bindComments($data['status']);
- return BaseApi::formatData('statuses', $type, $data);
+ return ApiResponse::formatData('statuses', $type, $data);
}
/// @TODO move to top of file or somewhere better
break;
}
- return BaseApi::formatData("statuses", $type, $data);
+ return ApiResponse::formatData("statuses", $type, $data);
}
break;
}
- return BaseApi::formatData("statuses", $type, $data);
+ return ApiResponse::formatData("statuses", $type, $data);
}
/// @TODO move to top of file or somewhere better
break;
}
- return BaseApi::formatData("statuses", $type, $data);
+ return ApiResponse::formatData("statuses", $type, $data);
}
/// @TODO move to top of file or somewhere better
if ($conversation) {
$data = ['status' => $ret];
- return BaseApi::formatData("statuses", $type, $data);
+ return ApiResponse::formatData("statuses", $type, $data);
} else {
$data = ['status' => $ret[0]];
- return BaseApi::formatData("status", $type, $data);
+ return ApiResponse::formatData("status", $type, $data);
}
}
$ret = api_format_items(Post::toArray($statuses), $user_info, false, $type);
$data = ['status' => $ret];
- return BaseApi::formatData("statuses", $type, $data);
+ return ApiResponse::formatData("statuses", $type, $data);
}
/// @TODO move to top of file or somewhere better
break;
}
- return BaseApi::formatData("statuses", $type, $data);
+ return ApiResponse::formatData("statuses", $type, $data);
}
/// @TODO move to top of file or somewhere better
break;
}
- return BaseApi::formatData("statuses", $type, $data);
+ return ApiResponse::formatData("statuses", $type, $data);
}
/// @TODO move to top of file or somewhere better
break;
}
- return BaseApi::formatData("status", $type, $data);
+ return ApiResponse::formatData("status", $type, $data);
}
/// @TODO move to top of file or somewhere better
break;
}
- return BaseApi::formatData("statuses", $type, $data);
+ return ApiResponse::formatData("statuses", $type, $data);
}
/// @TODO move to top of file or somewhere better
}
foreach ((array)$items as $item) {
- list($status_user, $author_user, $owner_user) = api_item_get_user($a, $item);
+ [$status_user, $author_user, $owner_user] = api_item_get_user($a, $item);
// Look if the posts are matching if they should be filtered by user id
if ($filter_user && ($status_user["id"] != $user_info["id"])) {
$a = Friendica\DI::app();
if (empty($status_user) || empty($author_user) || empty($owner_user)) {
- list($status_user, $author_user, $owner_user) = api_item_get_user($a, $item);
+ [$status_user, $author_user, $owner_user] = api_item_get_user($a, $item);
}
DI::contentItem()->localize($item);
{
$ret = [];
/// @TODO $ret is not filled here?
- return BaseApi::formatData('lists', $type, ["lists_list" => $ret]);
+ return ApiResponse::formatData('lists', $type, ["lists_list" => $ret]);
}
/// @TODO move to top of file or somewhere better
'mode' => $mode
];
}
- return BaseApi::formatData("lists", $type, ['lists' => ['lists' => $lists]]);
+ return ApiResponse::formatData("lists", $type, ['lists' => ['lists' => $lists]]);
}
/// @TODO move to top of file or somewhere better
break;
}
- return BaseApi::formatData("statuses", $type, $data);
+ return ApiResponse::formatData("statuses", $type, $data);
}
/// @TODO move to top of file or somewhere better
if ($data === false) {
return false;
}
- return BaseApi::formatData("users", $type, $data);
+ return ApiResponse::formatData("users", $type, $data);
}
/**
if ($data === false) {
return false;
}
- return BaseApi::formatData("users", $type, $data);
+ return ApiResponse::formatData("users", $type, $data);
}
/// @TODO move to top of file or somewhere better
if ($data === false) {
return false;
}
- return BaseApi::formatData("users", $type, $data);
+ return ApiResponse::formatData("users", $type, $data);
}
/// @TODO move to top of file or somewhere better
$ids[] = $user['id'];
}
- return BaseApi::formatData("ids", $type, ['id' => $ids]);
+ return ApiResponse::formatData("ids", $type, ['id' => $ids]);
}
/// @TODO move to top of file or somewhere better
],
];
- return BaseApi::formatData('config', $type, ['config' => $config]);
+ return ApiResponse::formatData('config', $type, ['config' => $config]);
}
/// @TODO move to top of file or somewhere better
break;
}
- return BaseApi::formatData("direct-messages", $type, $data);
+ return ApiResponse::formatData("direct-messages", $type, $data);
}
/// @TODO move to top of file or somewhere better
// error if no id or parenturi specified (for clients posting parent-uri as well)
if ($verbose == "true" && ($id == 0 || $parenturi == "")) {
$answer = ['result' => 'error', 'message' => 'message id or parenturi not specified'];
- return BaseApi::formatData("direct_messages_delete", $type, ['$result' => $answer]);
+ return ApiResponse::formatData("direct_messages_delete", $type, ['$result' => $answer]);
}
// BadRequestException if no id specified (for clients using Twitter API)
if (!DBA::exists('mail', ["`uid` = ? AND `id` = ? " . $sql_extra, $uid, $id])) {
if ($verbose == "true") {
$answer = ['result' => 'error', 'message' => 'message id not in database'];
- return BaseApi::formatData("direct_messages_delete", $type, ['$result' => $answer]);
+ return ApiResponse::formatData("direct_messages_delete", $type, ['$result' => $answer]);
}
/// @todo BadRequestException ok for Twitter API clients?
throw new BadRequestException('message id not in database');
if ($result) {
// return success
$answer = ['result' => 'ok', 'message' => 'message deleted'];
- return BaseApi::formatData("direct_message_delete", $type, ['$result' => $answer]);
+ return ApiResponse::formatData("direct_message_delete", $type, ['$result' => $answer]);
} else {
$answer = ['result' => 'error', 'message' => 'unknown error'];
- return BaseApi::formatData("direct_messages_delete", $type, ['$result' => $answer]);
+ return ApiResponse::formatData("direct_messages_delete", $type, ['$result' => $answer]);
}
}
/// @todo return JSON data like Twitter API not yet implemented
// Set screen_name since Twidere requests it
$contact['screen_name'] = $contact['nick'];
- return BaseApi::formatData('friendships-destroy', $type, ['user' => $contact]);
+ return ApiResponse::formatData('friendships-destroy', $type, ['user' => $contact]);
}
+
api_register_func('api/friendships/destroy', 'api_friendships_destroy', true, API_METHOD_POST);
/**
));
if ($verbose == "true" && !DBA::isResult($r)) {
$answer = ['result' => 'error', 'message' => 'no mails available'];
- return BaseApi::formatData("direct_messages_all", $type, ['$result' => $answer]);
+ return ApiResponse::formatData("direct_messages_all", $type, ['$result' => $answer]);
}
$ret = [];
break;
}
- return BaseApi::formatData("direct-messages", $type, $data);
+ return ApiResponse::formatData("direct-messages", $type, $data);
}
/**
}
}
}
- return BaseApi::formatData("photos", $type, $data);
+ return ApiResponse::formatData("photos", $type, $data);
}
/**
// return success of updating or error message
if (!is_null($data)) {
- return BaseApi::formatData("photo_create", $type, $data);
+ return ApiResponse::formatData("photo_create", $type, $data);
} else {
throw new InternalServerErrorException("unknown error - uploading photo failed, see Friendica log for more information");
}
$media = $_FILES['media'];
$data = save_media_to_database("photo", $media, $type, $album, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $desc, Photo::DEFAULT, $visibility, $photo_id);
if (!is_null($data)) {
- return BaseApi::formatData("photo_update", $type, $data);
+ return ApiResponse::formatData("photo_update", $type, $data);
}
}
// return success of updating or error message
if ($result) {
$answer = ['result' => 'updated', 'message' => 'Image id `' . $photo_id . '` has been updated.'];
- return BaseApi::formatData("photo_update", $type, ['$result' => $answer]);
+ return ApiResponse::formatData("photo_update", $type, ['$result' => $answer]);
} else {
if ($nothingtodo) {
$answer = ['result' => 'cancelled', 'message' => 'Nothing to update for image id `' . $photo_id . '`.'];
- return BaseApi::formatData("photo_update", $type, ['$result' => $answer]);
+ return ApiResponse::formatData("photo_update", $type, ['$result' => $answer]);
}
throw new InternalServerErrorException("unknown error - update photo entry in database failed");
}
// prepare json/xml output with data from database for the requested photo
$data = prepare_photo_data($type, $scale, $photo_id);
- return BaseApi::formatData("photo_detail", $type, $data);
+ return ApiResponse::formatData("photo_detail", $type, $data);
}
}
$grps[] = ['name' => $rr['name'], 'gid' => $rr['id'], $user_element => $users];
}
- return BaseApi::formatData("groups", $type, ['group' => $grps]);
+ return ApiResponse::formatData("groups", $type, ['group' => $grps]);
}
+
api_register_func('api/friendica/group_show', 'api_friendica_group_show', true);
if ($ret) {
// return success
$success = ['success' => $ret, 'gid' => $gid, 'name' => $name, 'status' => 'deleted', 'wrong users' => []];
- return BaseApi::formatData("group_delete", $type, ['result' => $success]);
+ return ApiResponse::formatData("group_delete", $type, ['result' => $success]);
} else {
throw new BadRequestException('other API error');
}
'user' => $user_info
];
- return BaseApi::formatData("lists", $type, ['lists' => $list]);
+ return ApiResponse::formatData("lists", $type, ['lists' => $list]);
}
}
+
api_register_func('api/lists/destroy', 'api_lists_destroy', true, API_METHOD_DELETE);
/**
$success = group_create($name, $uid, $users);
- return BaseApi::formatData("group_create", $type, ['result' => $success]);
+ return ApiResponse::formatData("group_create", $type, ['result' => $success]);
}
+
api_register_func('api/friendica/group_create', 'api_friendica_group_create', true, API_METHOD_POST);
/**
'user' => $user_info
];
- return BaseApi::formatData("lists", $type, ['lists'=>$grp]);
+ return ApiResponse::formatData("lists", $type, ['lists' => $grp]);
}
}
+
api_register_func('api/lists/create', 'api_lists_create', true, API_METHOD_POST);
/**
// return success message incl. missing users in array
$status = ($erroraddinguser ? "missing user" : "ok");
$success = ['success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers];
- return BaseApi::formatData("group_update", $type, ['result' => $success]);
+ return ApiResponse::formatData("group_update", $type, ['result' => $success]);
}
api_register_func('api/friendica/group_update', 'api_friendica_group_update', true, API_METHOD_POST);
'user' => $user_info
];
- return BaseApi::formatData("lists", $type, ['lists' => $list]);
+ return ApiResponse::formatData("lists", $type, ['lists' => $list]);
}
}
// we found the item, return it to the user
$ret = api_format_items([$item], $user_info, false, $type);
$data = ['status' => $ret];
- return BaseApi::formatData('status', $type, $data);
+ return ApiResponse::formatData('status', $type, $data);
}
// the item can't be found, but we set the notification as seen, so we count this as a success
}
- return BaseApi::formatData('result', $type, ['result' => 'success']);
+ return ApiResponse::formatData('result', $type, ['result' => 'success']);
} catch (NotFoundException $e) {
throw new BadRequestException('Invalid argument', $e);
} catch (Exception $e) {
// error if no searchstring specified
if ($searchstring == "") {
$answer = ['result' => 'error', 'message' => 'searchstring not specified'];
- return BaseApi::formatData("direct_messages_search", $type, ['$result' => $answer]);
+ return ApiResponse::formatData("direct_messages_search", $type, ['$result' => $answer]);
}
// get data for the specified searchstring
$success = ['success' => true, 'search_results' => $ret];
}
- return BaseApi::formatData("direct_message_search", $type, ['$result' => $success]);
+ return ApiResponse::formatData("direct_message_search", $type, ['$result' => $success]);
}
/// @TODO move to top of file or somewhere better
--- /dev/null
+<?php
+
+namespace Friendica\Module\Api;
+
+use Friendica\App\Arguments;
+use Friendica\Core\L10n;
+use Friendica\Core\Logger;
+use Friendica\Core\System;
+use Friendica\DI;
+use Friendica\Object\Api\Mastodon\Error;
+use Friendica\Util\Arrays;
+use Friendica\Util\HTTPInputData;
+use Friendica\Util\XML;
+
+/**
+ * This class is used to format and return API responses
+ */
+class ApiResponse
+{
+ /** @var L10n */
+ protected $l10n;
+ /** @var Arguments */
+ protected $args;
+
+ /**
+ * @param L10n $l10n
+ * @param Arguments $args
+ */
+ public function __construct(L10n $l10n, Arguments $args)
+ {
+ $this->l10n = $l10n;
+ $this->args = $args;
+ }
+
+ /**
+ * Creates the XML from a JSON style array
+ *
+ * @param array $data JSON style array
+ * @param string $root_element Name of the root element
+ *
+ * @return string The XML data
+ */
+ public static function createXML(array $data, string $root_element): string
+ {
+ $childname = key($data);
+ $data2 = array_pop($data);
+
+ $namespaces = ['' => 'http://api.twitter.com',
+ 'statusnet' => 'http://status.net/schema/api/1/',
+ 'friendica' => 'http://friendi.ca/schema/api/1/',
+ 'georss' => 'http://www.georss.org/georss'];
+
+ /// @todo Auto detection of needed namespaces
+ if (in_array($root_element, ['ok', 'hash', 'config', 'version', 'ids', 'notes', 'photos'])) {
+ $namespaces = [];
+ }
+
+ if (is_array($data2)) {
+ $key = key($data2);
+ Arrays::walkRecursive($data2, ['Friendica\Module\Api\ApiResponse', 'reformatXML']);
+
+ if ($key == '0') {
+ $data4 = [];
+ $i = 1;
+
+ foreach ($data2 as $item) {
+ $data4[$i++ . ':' . $childname] = $item;
+ }
+
+ $data2 = $data4;
+ }
+ }
+
+ $data3 = [$root_element => $data2];
+
+ return XML::fromArray($data3, $xml, false, $namespaces);
+ }
+
+ /**
+ * Formats the data according to the data type
+ *
+ * @param string $root_element Name of the root element
+ * @param string $type Return type (atom, rss, xml, json)
+ * @param array $data JSON style array
+ *
+ * @return array|string (string|array) XML data or JSON data
+ */
+ public static function formatData(string $root_element, string $type, array $data)
+ {
+ switch ($type) {
+ case 'atom':
+ case 'rss':
+ case 'xml':
+ $ret = static::createXML($data, $root_element);
+ break;
+ case 'json':
+ default:
+ $ret = $data;
+ break;
+ }
+ return $ret;
+ }
+
+ /**
+ * Callback function to transform the array in an array that can be transformed in a XML file
+ *
+ * @param mixed $item Array item value
+ * @param string $key Array key
+ *
+ * @return boolean
+ */
+ public static function reformatXML(&$item, string &$key): bool
+ {
+ if (is_bool($item)) {
+ $item = ($item ? 'true' : 'false');
+ }
+
+ if (substr($key, 0, 10) == 'statusnet_') {
+ $key = 'statusnet:' . substr($key, 10);
+ } elseif (substr($key, 0, 10) == 'friendica_') {
+ $key = 'friendica:' . substr($key, 10);
+ }
+ return true;
+ }
+
+ /**
+ * Exit with error code
+ *
+ * @param int $code
+ * @param string $description
+ * @param string $message
+ * @param string|null $format
+ *
+ * @return void
+ */
+ public static function error(int $code, string $description, string $message, string $format = null)
+ {
+ $error = [
+ 'error' => $message ?: $description,
+ 'code' => $code . ' ' . $description,
+ 'request' => DI::args()->getQueryString()
+ ];
+
+ header(($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1') . ' ' . $code . ' ' . $description);
+
+ self::exit('status', ['status' => $error], $format);
+ }
+
+ /**
+ * Outputs formatted data according to the data type and then exits the execution.
+ *
+ * @param string $root_element
+ * @param array $data An array with a single element containing the returned result
+ * @param string|null $format Output format (xml, json, rss, atom)
+ *
+ * @return void
+ */
+ public static function exit(string $root_element, array $data, string $format = null)
+ {
+ $format = $format ?? 'json';
+
+ $return = static::formatData($root_element, $format, $data);
+
+ switch ($format) {
+ case 'xml':
+ header('Content-Type: text/xml');
+ break;
+ case 'json':
+ header('Content-Type: application/json');
+ if (!empty($return)) {
+ $json = json_encode(end($return));
+ if (!empty($_GET['callback'])) {
+ $json = $_GET['callback'] . '(' . $json . ')';
+ }
+ $return = $json;
+ }
+ break;
+ case 'rss':
+ header('Content-Type: application/rss+xml');
+ $return = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $return;
+ break;
+ case 'atom':
+ header('Content-Type: application/atom+xml');
+ $return = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $return;
+ break;
+ }
+
+ echo $return;
+ exit;
+ }
+
+ /**
+ * Quit execution with the message that the endpoint isn't implemented
+ *
+ * @param string $method
+ *
+ * @return void
+ * @throws \Exception
+ */
+ public static function unsupported(string $method = 'all')
+ {
+ $path = DI::args()->getQueryString();
+ Logger::info('Unimplemented API call',
+ [
+ 'method' => $method,
+ 'path' => $path,
+ 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
+ 'request' => HTTPInputData::process()
+ ]);
+ $error = DI::l10n()->t('API endpoint %s %s is not implemented', strtoupper($method), $path);
+ $error_description = DI::l10n()->t('The API endpoint is currently not implemented but might be in the future.');
+ $errorobj = new Error($error, $error_description);
+ System::jsonError(501, $errorobj->toArray());
+ }
+}
namespace Friendica\Module\Api\Friendica;
use Friendica\Model\Item;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
} else {
$ok = 'ok';
}
- self::exit('ok', ['ok' => $ok], $parameters['extension'] ?? null);
+ ApiResponse::exit('ok', ['ok' => $ok], $parameters['extension'] ?? null);
} else {
- self::error(500, 'Error adding activity', '', $parameters['extension'] ?? null);
+ ApiResponse::error(500, 'Error adding activity', '', $parameters['extension'] ?? null);
}
}
}
namespace Friendica\Module\Api\Friendica\DirectMessages;
use Friendica\Database\DBA;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
// return error if id is zero
if (empty($request['id'])) {
$answer = ['result' => 'error', 'message' => 'message id not specified'];
- self::exit('direct_messages_setseen', ['$result' => $answer], $parameters['extension'] ?? null);
+ ApiResponse::exit('direct_messages_setseen', ['$result' => $answer], $parameters['extension'] ?? null);
}
// error message if specified id is not in database
if (!DBA::exists('mail', ['id' => $request['id'], 'uid' => $uid])) {
$answer = ['result' => 'error', 'message' => 'message id not in database'];
- self::exit('direct_messages_setseen', ['$result' => $answer], $parameters['extension'] ?? null);
+ ApiResponse::exit('direct_messages_setseen', ['$result' => $answer], $parameters['extension'] ?? null);
}
// update seen indicator
$answer = ['result' => 'error', 'message' => 'unknown error'];
}
- self::exit('direct_messages_setseen', ['$result' => $answer], $parameters['extension'] ?? null);
+ ApiResponse::exit('direct_messages_setseen', ['$result' => $answer], $parameters['extension'] ?? null);
}
}
use Friendica\Content\Text\BBCode;
use Friendica\Database\DBA;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException;
];
}
- self::exit('events', ['events' => $items], $parameters['extension'] ?? null);
+ ApiResponse::exit('events', ['events' => $items], $parameters['extension'] ?? null);
}
}
use Friendica\Collection\Api\Notifications as ApiNotifications;
use Friendica\DI;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Object\Api\Friendica\Notification as ApiNotification;
$result = false;
}
- self::exit('notes', ['note' => $result], $parameters['extension'] ?? null);
+ ApiResponse::exit('notes', ['note' => $result], $parameters['extension'] ?? null);
}
}
use Friendica\Model\Item;
use Friendica\Model\Photo;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException\BadRequestException;
use Friendica\Network\HTTPException\InternalServerErrorException;
Item::deleteForUser($condition, $uid);
$result = ['result' => 'deleted', 'message' => 'photo with id `' . $request['photo_id'] . '` has been deleted from server.'];
- self::exit('photo_delete', ['$result' => $result], $parameters['extension'] ?? null);
+ ApiResponse::exit('photo_delete', ['$result' => $result], $parameters['extension'] ?? null);
} else {
throw new InternalServerErrorException("unknown error on deleting photo from database table");
}
use Friendica\Database\DBA;
use Friendica\Model\Item;
use Friendica\Model\Photo;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException\BadRequestException;
use Friendica\Network\HTTPException\InternalServerErrorException;
// return success of deletion or error message
if ($result) {
$answer = ['result' => 'deleted', 'message' => 'album `' . $request['album'] . '` with all containing photos has been deleted.'];
- self::exit('photoalbum_delete', ['$result' => $answer], $parameters['extension'] ?? null);
+ ApiResponse::exit('photoalbum_delete', ['$result' => $answer], $parameters['extension'] ?? null);
} else {
throw new InternalServerErrorException("unknown error - deleting from database failed");
}
namespace Friendica\Module\Api\Friendica\Photoalbum;
use Friendica\Model\Photo;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException\BadRequestException;
use Friendica\Network\HTTPException\InternalServerErrorException;
// return success of updating or error message
if ($result) {
$answer = ['result' => 'updated', 'message' => 'album `' . $request['album'] . '` with all containing photos has been renamed to `' . $request['album_new'] . '`.'];
- self::exit('photoalbum_update', ['$result' => $answer], $parameters['extension'] ?? null);
+ ApiResponse::exit('photoalbum_update', ['$result' => $answer], $parameters['extension'] ?? null);
} else {
throw new InternalServerErrorException("unknown error - updating in database failed");
}
namespace Friendica\Module\Api\Friendica\Profile;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Profile\ProfileField\Collection\ProfileFields;
use Friendica\Content\Text\BBCode;
use Friendica\DI;
'profiles' => $profiles
];
- self::exit('friendica_profiles', ['$result' => $result], $parameters['extension'] ?? null);
+ ApiResponse::exit('friendica_profiles', ['$result' => $result], $parameters['extension'] ?? null);
}
/**
namespace Friendica\Module\Api\GNUSocial\GNUSocial;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
{
public static function rawContent(array $parameters = [])
{
- self::exit('version', ['version' => '0.9.7'], $parameters['extension'] ?? null);
+ ApiResponse::exit('version', ['version' => '0.9.7'], $parameters['extension'] ?? null);
}
}
namespace Friendica\Module\Api\GNUSocial\Help;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
$ok = 'ok';
}
- self::exit('ok', ['ok' => $ok], $parameters['extension'] ?? null);
+ ApiResponse::exit('ok', ['ok' => $ok], $parameters['extension'] ?? null);
}
}
use Friendica\App\Router;
use Friendica\Core\Logger;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Util\HTTPInputData;
Logger::info('Patch data', ['data' => $data]);
- self::unsupported(Router::PATCH);
+ ApiResponse::unsupported(Router::PATCH);
}
}
use Friendica\App\Router;
use Friendica\Core\System;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
{
self::checkAllowedScope(self::SCOPE_WRITE);
- self::unsupported(Router::POST);
+ ApiResponse::unsupported(Router::POST);
}
/**
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\DI;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
{
public static function delete(array $parameters = [])
{
- self::unsupported(Router::DELETE);
+ ApiResponse::unsupported(Router::DELETE);
}
public static function post(array $parameters = [])
{
- self::unsupported(Router::POST);
+ ApiResponse::unsupported(Router::POST);
}
/**
use Friendica\App\Router;
use Friendica\Core\System;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
{
self::checkAllowedScope(self::SCOPE_WRITE);
- self::unsupported(Router::POST);
+ ApiResponse::unsupported(Router::POST);
}
/**
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Post;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
- self::unsupported(Router::PUT);
+ ApiResponse::unsupported(Router::PUT);
}
public static function delete(array $parameters = [])
namespace Friendica\Module\Api\Mastodon;
use Friendica\App\Router;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
*/
public static function delete(array $parameters = [])
{
- self::unsupported(Router::DELETE);
+ ApiResponse::unsupported(Router::DELETE);
}
/**
*/
public static function patch(array $parameters = [])
{
- self::unsupported(Router::PATCH);
+ ApiResponse::unsupported(Router::PATCH);
}
/**
*/
public static function post(array $parameters = [])
{
- self::unsupported(Router::POST);
+ ApiResponse::unsupported(Router::POST);
}
/**
*/
public static function put(array $parameters = [])
{
- self::unsupported(Router::PUT);
+ ApiResponse::unsupported(Router::PUT);
}
/**
*/
public static function rawContent(array $parameters = [])
{
- self::unsupported(Router::GET);
+ ApiResponse::unsupported(Router::GET);
}
}
namespace Friendica\Module\Api\Twitter\Account;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Util\DateTimeFormat;
];
}
- self::exit('hash', ['hash' => $hash], $parameters['extension'] ?? null);
+ ApiResponse::exit('hash', ['hash' => $hash], $parameters['extension'] ?? null);
}
}
namespace Friendica\Module\Api\Twitter;
use Friendica\Database\DBA;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
/**
DBA::close($terms);
- self::exit('terms', ['terms' => $result], $parameters['extension'] ?? null);
+ ApiResponse::exit('terms', ['terms' => $result], $parameters['extension'] ?? null);
}
}
}
}
- /**
- * Quit execution with the message that the endpoint isn't implemented
- *
- * @param string $method
- * @return void
- */
- public static function unsupported(string $method = 'all')
- {
- $path = DI::args()->getQueryString();
- Logger::info('Unimplemented API call', ['method' => $method, 'path' => $path, 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'request' => HTTPInputData::process()]);
- $error = DI::l10n()->t('API endpoint %s %s is not implemented', strtoupper($method), $path);
- $error_description = DI::l10n()->t('The API endpoint is currently not implemented but might be in the future.');
- $errorobj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description);
- System::jsonError(501, $errorobj->toArray());
- }
-
/**
* Processes data from GET requests and sets defaults
*
{
return api_get_user($contact_id);
}
-
- /**
- * Exit with error code
- *
- * @param int $code
- * @param string $description
- * @param string $message
- * @param string|null $format
- * @return void
- */
- public static function error(int $code, string $description, string $message, string $format = null)
- {
- $error = [
- 'error' => $message ?: $description,
- 'code' => $code . ' ' . $description,
- 'request' => DI::args()->getQueryString()
- ];
-
- header(($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1') . ' ' . $code . ' ' . $description);
-
- self::exit('status', ['status' => $error], $format);
- }
-
- /**
- * Outputs formatted data according to the data type and then exits the execution.
- *
- * @param string $root_element
- * @param array $data An array with a single element containing the returned result
- * @param string $format Output format (xml, json, rss, atom)
- * @return false|string
- */
- protected static function exit(string $root_element, array $data, string $format = null)
- {
- $format = $format ?? 'json';
-
- $return = self::formatData($root_element, $format, $data);
-
- switch ($format) {
- case 'xml':
- header('Content-Type: text/xml');
- break;
- case 'json':
- header('Content-Type: application/json');
- if (!empty($return)) {
- $json = json_encode(end($return));
- if (!empty($_GET['callback'])) {
- $json = $_GET['callback'] . '(' . $json . ')';
- }
- $return = $json;
- }
- break;
- case 'rss':
- header('Content-Type: application/rss+xml');
- $return = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $return;
- break;
- case 'atom':
- header('Content-Type: application/atom+xml');
- $return = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $return;
- break;
- }
-
- echo $return;
- exit;
- }
-
- /**
- * Formats the data according to the data type
- *
- * @param string $root_element Name of the root element
- * @param string $type Return type (atom, rss, xml, json)
- * @param array $data JSON style array
- *
- * @return array|string (string|array) XML data or JSON data
- */
- public static function formatData($root_element, string $type, array $data)
- {
- switch ($type) {
- case 'atom':
- case 'rss':
- case 'xml':
- $ret = self::createXML($data, $root_element);
- break;
- case 'json':
- default:
- $ret = $data;
- break;
- }
- return $ret;
- }
-
- /**
- * Callback function to transform the array in an array that can be transformed in a XML file
- *
- * @param mixed $item Array item value
- * @param string $key Array key
- *
- * @return boolean
- */
- public static function reformatXML(&$item, &$key)
- {
- if (is_bool($item)) {
- $item = ($item ? 'true' : 'false');
- }
-
- if (substr($key, 0, 10) == 'statusnet_') {
- $key = 'statusnet:'.substr($key, 10);
- } elseif (substr($key, 0, 10) == 'friendica_') {
- $key = 'friendica:'.substr($key, 10);
- }
- return true;
- }
-
- /**
- * Creates the XML from a JSON style array
- *
- * @param array $data JSON style array
- * @param string $root_element Name of the root element
- *
- * @return string The XML data
- */
- public static function createXML(array $data, $root_element)
- {
- $childname = key($data);
- $data2 = array_pop($data);
-
- $namespaces = ['' => 'http://api.twitter.com',
- 'statusnet' => 'http://status.net/schema/api/1/',
- 'friendica' => 'http://friendi.ca/schema/api/1/',
- 'georss' => 'http://www.georss.org/georss'];
-
- /// @todo Auto detection of needed namespaces
- if (in_array($root_element, ['ok', 'hash', 'config', 'version', 'ids', 'notes', 'photos'])) {
- $namespaces = [];
- }
-
- if (is_array($data2)) {
- $key = key($data2);
- Arrays::walkRecursive($data2, ['Friendica\Module\BaseApi', 'reformatXML']);
-
- if ($key == '0') {
- $data4 = [];
- $i = 1;
-
- foreach ($data2 as $item) {
- $data4[$i++ . ':' . $childname] = $item;
- }
-
- $data2 = $data4;
- }
- }
-
- $data3 = [$root_element => $data2];
-
- $ret = XML::fromArray($data3, $xml, false, $namespaces);
- return $ret;
- }
}
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Protocol;
use Friendica\DI;
+use Friendica\Module\Api\ApiResponse;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException;
use Friendica\Security\BasicAuth;
{
$item = true;
$key = '';
- self::assertTrue(BaseApi::reformatXML($item, $key));
+ self::assertTrue(ApiResponse::reformatXML($item, $key));
self::assertEquals('true', $item);
}
{
$item = '';
$key = 'statusnet_api';
- self::assertTrue(BaseApi::reformatXML($item, $key));
+ self::assertTrue(ApiResponse::reformatXML($item, $key));
self::assertEquals('statusnet:api', $key);
}
{
$item = '';
$key = 'friendica_api';
- self::assertTrue(BaseApi::reformatXML($item, $key));
+ self::assertTrue(ApiResponse::reformatXML($item, $key));
self::assertEquals('friendica:api', $key);
}
'xmlns:georss="http://www.georss.org/georss">' . "\n" .
' <data>some_data</data>' . "\n" .
'</root_element>' . "\n",
- BaseApi::createXML(['data' => ['some_data']], 'root_element')
+ ApiResponse::createXML(['data' => ['some_data']], 'root_element')
);
}
'<ok>' . "\n" .
' <data>some_data</data>' . "\n" .
'</ok>' . "\n",
- BaseApi::createXML(['data' => ['some_data']], 'ok')
+ ApiResponse::createXML(['data' => ['some_data']], 'ok')
);
}
public function testApiFormatData()
{
$data = ['some_data'];
- self::assertEquals($data, BaseApi::formatData('root_element', 'json', $data));
+ self::assertEquals($data, ApiResponse::formatData('root_element', 'json', $data));
}
/**
'xmlns:georss="http://www.georss.org/georss">' . "\n" .
' <data>some_data</data>' . "\n" .
'</root_element>' . "\n",
- BaseApi::formatData('root_element', 'xml', ['data' => ['some_data']])
+ ApiResponse::formatData('root_element', 'xml', ['data' => ['some_data']])
);
}