X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=include%2Fapi.php;h=d4007564f39aef6973226317e82fd9b20022933d;hb=c69d60644f46246978a7b52da79e7e58c74e31e6;hp=724568279aad61612d13d185c99472897b1383b5;hpb=37aef324406498445770f41f7d5b921ad6599b77;p=friendica.git diff --git a/include/api.php b/include/api.php index 724568279a..d4007564f3 100644 --- a/include/api.php +++ b/include/api.php @@ -1,11 +1,12 @@ ". * Some clients doesn't send a source param, we support ones we know * (only Twidere, atm) * + * @brief Get source name from API client + * * @return string * Client source name, default to "api" if unset/unknown */ @@ -110,9 +111,9 @@ function api_date($str) } /** - * @brief Register API endpoint + * Register a function to be the endpoint for defined API path. * - * Register a function to be the endpont for defined API path. + * @brief Register API endpoint * * @param string $path API URL path, relative to System::baseUrl() * @param string $func Function name to call on path request @@ -125,28 +126,28 @@ function api_register_func($path, $func, $auth = false, $method = API_METHOD_ANY { global $API; - $API[$path] = array( + $API[$path] = [ 'func' => $func, 'auth' => $auth, 'method' => $method, - ); + ]; // Workaround for hotot $path = str_replace("api/", "api/1.1/", $path); - $API[$path] = array( + $API[$path] = [ 'func' => $func, 'auth' => $auth, 'method' => $method, - ); + ]; } /** - * @brief Login API user - * * Log in user via OAuth1 or Simple HTTP Auth. * Simple Auth allow username in form of
user@server
, ignoring server part * + * @brief Login API user + * * @param object $a App * @hook 'authenticate' * array $addon_auth @@ -186,7 +187,7 @@ function api_login(App $a) } if (!x($_SERVER, 'PHP_AUTH_USER')) { - logger('API_login: ' . print_r($_SERVER,true), LOGGER_DEBUG); + logger('API_login: ' . print_r($_SERVER, true), LOGGER_DEBUG); header('WWW-Authenticate: Basic realm="Friendica"'); throw new UnauthorizedException("This API requires login"); } @@ -203,12 +204,12 @@ function api_login(App $a) // next code from mod/auth.php. needs better solution $record = null; - $addon_auth = array( + $addon_auth = [ 'username' => trim($user), 'password' => trim($password), 'authenticated' => 0, 'user_record' => null, - ); + ]; /* * A plugin indicates successful login by setting 'authenticated' to non-zero value and returning a user record @@ -217,16 +218,16 @@ function api_login(App $a) */ call_hooks('authenticate', $addon_auth); - if (($addon_auth['authenticated']) && (count($addon_auth['user_record']))) { + if ($addon_auth['authenticated'] && count($addon_auth['user_record'])) { $record = $addon_auth['user_record']; } else { $user_id = User::authenticate(trim($user), trim($password)); if ($user_id) { - $record = dba::select('user', [], ['uid' => $user_id], ['limit' => 1]); + $record = dba::selectFirst('user', [], ['uid' => $user_id]); } } - if ((! $record) || (! count($record))) { + if (!DBM::is_result($record)) { logger('API_login failure: ' . print_r($_SERVER, true), LOGGER_DEBUG); header('WWW-Authenticate: Basic realm="Friendica"'); //header('HTTP/1.0 401 Unauthorized'); @@ -242,12 +243,12 @@ function api_login(App $a) } /** - * @brief Check HTTP method of called API - * * API endpoints can define which HTTP method to accept when called. * This function check the current HTTP method agains endpoint * registered method. * + * @brief Check HTTP method of called API + * * @param string $method Required methods, uppercase, separated by comma * @return bool */ @@ -260,10 +261,10 @@ function api_check_method($method) } /** - * @brief Main API entry point - * * Authenticate user, call registered API function, set HTTP headers * + * @brief Main API entry point + * * @param object $a App * @return string API call result */ @@ -304,7 +305,7 @@ function api_call(App $a) logger('API parameters: ' . print_r($_REQUEST, true)); $stamp = microtime(true); - $r = call_user_func($info['func'], $type); + $return = call_user_func($info['func'], $type); $duration = (float) (microtime(true) - $stamp); logger("API call duration: " . round($duration, 2) . "\t" . $a->query_string, LOGGER_DEBUG); @@ -352,7 +353,7 @@ function api_call(App $a) } } - if (false === $r) { + if (false === $return) { /* * api function returned false withour throw an * exception. This should not happend, throw a 500 @@ -363,26 +364,27 @@ function api_call(App $a) switch ($type) { case "xml": header("Content-Type: text/xml"); - return $r; break; case "json": header("Content-Type: application/json"); - foreach ($r as $rr) + foreach ($return as $rr) { $json = json_encode($rr); - if (x($_GET, 'callback')) { - $json = $_GET['callback'] . "(" . $json . ")"; - } - return $json; + } + if (x($_GET, 'callback')) { + $json = $_GET['callback'] . "(" . $json . ")"; + } + $return = $json; break; case "rss": header("Content-Type: application/rss+xml"); - return '' . "\n" . $r; + $return = '' . "\n" . $return; break; case "atom": header("Content-Type: application/atom+xml"); - return '' . "\n" . $r; + $return = '' . "\n" . $return; break; } + return $return; } } @@ -408,30 +410,29 @@ function api_error($type, $e) $error = ($e->getMessage() !== "" ? $e->getMessage() : $e->httpdesc); /// @TODO: https://dev.twitter.com/overview/api/response-codes - $error = array("error" => $error, + $error = ["error" => $error, "code" => $e->httpcode . " " . $e->httpdesc, - "request" => $a->query_string); + "request" => $a->query_string]; - $ret = api_format_data('status', $type, array('status' => $error)); + $return = api_format_data('status', $type, ['status' => $error]); switch ($type) { case "xml": header("Content-Type: text/xml"); - return $ret; break; case "json": header("Content-Type: application/json"); - return json_encode($ret); + $return = json_encode($return); break; case "rss": header("Content-Type: application/rss+xml"); - return $ret; break; case "atom": header("Content-Type: application/atom+xml"); - return $ret; break; } + + return $return; } /** @@ -450,7 +451,7 @@ function api_rss_extra(App $a, $arr, $user_info) } $arr['$user'] = $user_info; - $arr['$rss'] = array( + $arr['$rss'] = [ 'alternate' => $user_info['url'], 'self' => System::baseUrl() . "/" . $a->query_string, 'base' => System::baseUrl(), @@ -458,7 +459,7 @@ function api_rss_extra(App $a, $arr, $user_info) 'atom_updated' => datetime_convert('UTC', 'UTC', 'now', ATOM_TIME), 'language' => $user_info['language'], 'logo' => System::baseUrl() . "/images/friendica-32.png", - ); + ]; return $arr; } @@ -473,7 +474,7 @@ function api_rss_extra(App $a, $arr, $user_info) */ function api_unique_id_to_nurl($id) { - $r = dba::select('contact', array('nurl'), array('uid' => 0, 'id' => $id), array('limit' => 1)); + $r = dba::selectFirst('contact', ['nurl'], ['uid' => 0, 'id' => $id]); if (DBM::is_result($r)) { return $r["nurl"]; @@ -495,7 +496,6 @@ function api_get_user(App $a, $contact_id = null) $user = null; $extra_query = ""; $url = ""; - $nick = ""; logger("api_get_user: Fetching user data for user ".$contact_id, LOGGER_DEBUG); @@ -539,7 +539,6 @@ function api_get_user(App $a, $contact_id = null) } if (is_null($user) && x($_GET, 'screen_name')) { $user = dbesc($_GET['screen_name']); - $nick = $user; $extra_query = "AND `contact`.`nick` = '%s' "; if (api_user() !== false) { $extra_query .= "AND `contact`.`uid`=".intval(api_user()); @@ -548,7 +547,6 @@ function api_get_user(App $a, $contact_id = null) if (is_null($user) && x($_GET, 'profileurl')) { $user = dbesc(normalise_link($_GET['profileurl'])); - $nick = $user; $extra_query = "AND `contact`.`nurl` = '%s' "; if (api_user() !== false) { $extra_query .= "AND `contact`.`uid`=".intval(api_user()); @@ -572,7 +570,6 @@ function api_get_user(App $a, $contact_id = null) } } else { $user = dbesc($user); - $nick = $user; $extra_query = "AND `contact`.`nick` = '%s' "; if (api_user() !== false) { $extra_query .= "AND `contact`.`uid`=" . intval(api_user()); @@ -607,21 +604,21 @@ function api_get_user(App $a, $contact_id = null) // if the contact wasn't found, fetch it from the contacts with uid = 0 if (!DBM::is_result($uinfo)) { - $r = array(); + $r = []; if ($url != "") { $r = q("SELECT * FROM `contact` WHERE `uid` = 0 AND `nurl` = '%s' LIMIT 1", dbesc(normalise_link($url))); } if (DBM::is_result($r)) { - $network_name = network_to_name($r[0]['network'], $r[0]['url']); + $network_name = ContactSelector::networkToName($r[0]['network'], $r[0]['url']); // If no nick where given, extract it from the address if (($r[0]['nick'] == "") || ($r[0]['name'] == $r[0]['nick'])) { $r[0]['nick'] = api_get_nick($r[0]["url"]); } - $ret = array( + $ret = [ 'id' => $r[0]["id"], 'id_str' => (string) $r[0]["id"], 'name' => $r[0]["name"], @@ -655,7 +652,7 @@ function api_get_user(App $a, $contact_id = null) 'cid' => Contact::getIdForURL($r[0]["url"], api_user(), true), 'self' => 0, 'network' => $r[0]["network"], - ); + ]; return $ret; } else { @@ -738,17 +735,31 @@ function api_get_user(App $a, $contact_id = null) $uinfo[0]['nick'] = api_get_nick($uinfo[0]["url"]); } - $network_name = network_to_name($uinfo[0]['network'], $uinfo[0]['url']); + $network_name = ContactSelector::networkToName($uinfo[0]['network'], $uinfo[0]['url']); $pcontact_id = Contact::getIdForURL($uinfo[0]['url'], 0, true); - $ret = array( + if (!empty($profile[0]['about'])) { + $description = $profile[0]['about']; + } else { + $description = $uinfo[0]["about"]; + } + + if (!empty($usr[0]['default-location'])) { + $location = $usr[0]['default-location']; + } elseif (!empty($uinfo[0]["location"])) { + $location = $uinfo[0]["location"]; + } else { + $location = $network_name; + } + + $ret = [ 'id' => intval($pcontact_id), 'id_str' => (string) intval($pcontact_id), 'name' => (($uinfo[0]['name']) ? $uinfo[0]['name'] : $uinfo[0]['nick']), 'screen_name' => (($uinfo[0]['nick']) ? $uinfo[0]['nick'] : $uinfo[0]['name']), - 'location' => ($usr) ? $usr[0]['default-location'] : $network_name, - 'description' => (($profile) ? $profile[0]['pdesc'] : null), + 'location' => $location, + 'description' => $description, 'profile_image_url' => $uinfo[0]['micro'], 'profile_image_url_https' => $uinfo[0]['micro'], 'url' => $uinfo[0]['url'], @@ -778,11 +789,11 @@ function api_get_user(App $a, $contact_id = null) 'cid' => intval($uinfo[0]['cid']), 'self' => $uinfo[0]['self'], 'network' => $uinfo[0]['network'], - ); + ]; // If this is a local user and it uses Frio, we can get its color preferences. if ($ret['self']) { - $theme_info = dba::select('user', ['theme'], ['uid' => $ret['uid']], ['limit' => 1]); + $theme_info = dba::selectFirst('user', ['theme'], ['uid' => $ret['uid']]); if ($theme_info['theme'] === 'frio') { $schema = PConfig::get($ret['uid'], 'frio', 'schema'); if ($schema && ($schema != '---')) { @@ -837,7 +848,7 @@ function api_item_get_user(App $a, $item) $owner_user = $status_user; } - return (array($status_user, $owner_user)); + return ([$status_user, $owner_user]); } /** @@ -850,7 +861,7 @@ function api_item_get_user(App $a, $item) */ function api_walk_recursive(array &$array, callable $callback) { - $new_array = array(); + $new_array = []; foreach ($array as $k => $v) { if (is_array($v)) { @@ -908,14 +919,14 @@ function api_create_xml($data, $root_element) $data2 = array_pop($data); $key = key($data2); - $namespaces = array("" => "http://api.twitter.com", + $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"); + "georss" => "http://www.georss.org/georss"]; /// @todo Auto detection of needed namespaces - if (in_array($root_element, array("ok", "hash", "config", "version", "ids", "notes", "photos"))) { - $namespaces = array(); + if (in_array($root_element, ["ok", "hash", "config", "version", "ids", "notes", "photos"])) { + $namespaces = []; } if (is_array($data2)) { @@ -923,7 +934,7 @@ function api_create_xml($data, $root_element) } if ($key == "0") { - $data4 = array(); + $data4 = []; $i = 1; foreach ($data2 as $item) { @@ -933,7 +944,7 @@ function api_create_xml($data, $root_element) $data2 = $data4; } - $data3 = array($root_element => $data2); + $data3 = [$root_element => $data2]; $ret = XML::fromArray($data3, $xml, false, $namespaces); return $ret; @@ -946,7 +957,7 @@ function api_create_xml($data, $root_element) * @param string $type Return type (atom, rss, xml, json) * @param array $data JSON style array * - * @return (string|object) XML data or JSON data + * @return (string|object|array) XML data or JSON data */ function api_format_data($root_element, $type, $data) { @@ -971,7 +982,9 @@ function api_format_data($root_element, $type, $data) /** * Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; * returns a 401 status code and an error message if not. - * http://developer.twitter.com/doc/get/account/verify_credentials + * @see https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials + * + * @param string $type Return type (atom, rss, xml, json) */ function api_account_verify_credentials($type) { @@ -1009,14 +1022,16 @@ function api_account_verify_credentials($type) unset($user_info["uid"]); unset($user_info["self"]); - return api_format_data("user", $type, array('user' => $user_info)); + return api_format_data("user", $type, ['user' => $user_info]); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/account/verify_credentials', 'api_account_verify_credentials', true); /** * Get data from $_POST or $_GET + * + * @param string $k */ function requestdata($k) { @@ -1029,7 +1044,13 @@ function requestdata($k) return null; } -/*Waitman Gobble Mod*/ +/** + * Waitman Gobble Mod + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_statuses_mediap($type) { $a = get_app(); @@ -1073,6 +1094,14 @@ function api_statuses_mediap($type) /// @TODO move this to top of file or somewhere better! api_register_func('api/statuses/mediap', 'api_statuses_mediap', true, API_METHOD_POST); +/** + * Updates the user’s current status. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + * @see https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update + */ function api_statuses_update($type) { @@ -1083,12 +1112,9 @@ function api_statuses_update($type) throw new ForbiddenException(); } - $user_info = api_get_user($a); + api_get_user($a); // convert $_POST array items to the form we use for web posts. - - // logger('api_post: ' . print_r($_POST,true)); - if (requestdata('htmlstatus')) { $txt = requestdata('htmlstatus'); if ((strpos($txt, '<') !== false) || (strpos($txt, '>') !== false)) { @@ -1244,11 +1270,17 @@ function api_statuses_update($type) return api_status_show($type); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/statuses/update', 'api_statuses_update', true, API_METHOD_POST); api_register_func('api/statuses/update_with_media', 'api_statuses_update', true, API_METHOD_POST); -function api_media_upload($type) +/** + * Uploads an image to Friendica. + * + * @return array + * @see https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-upload + */ +function api_media_upload() { $a = get_app(); @@ -1257,7 +1289,7 @@ function api_media_upload($type) throw new ForbiddenException(); } - $user_info = api_get_user($a); + api_get_user($a); if (!x($_FILES, 'media')) { // Output error @@ -1270,22 +1302,28 @@ function api_media_upload($type) throw new InternalServerErrorException(); } - $returndata = array(); + $returndata = []; $returndata["media_id"] = $media["id"]; $returndata["media_id_string"] = (string)$media["id"]; $returndata["size"] = $media["size"]; - $returndata["image"] = array("w" => $media["width"], + $returndata["image"] = ["w" => $media["width"], "h" => $media["height"], - "image_type" => $media["type"]); + "image_type" => $media["type"]]; logger("Media uploaded: " . print_r($returndata, true), LOGGER_DEBUG); - return array("media" => $returndata); + return ["media" => $returndata]; } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/media/upload', 'api_media_upload', true, API_METHOD_POST); +/** + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_status_show($type) { $a = get_app(); @@ -1330,7 +1368,7 @@ function api_status_show($type) $geo = "geo"; } - $status_info = array( + $status_info = [ 'created_at' => api_date($lastwall['created']), 'id' => intval($lastwall['id']), 'id_str' => (string) $lastwall['id'], @@ -1357,7 +1395,7 @@ function api_status_show($type) 'statusnet_html' => $converted["html"], 'statusnet_conversation_id' => $lastwall['parent'], 'external_url' => System::baseUrl() . "/display/" . $lastwall['guid'], - ); + ]; if (count($converted["attachments"]) > 0) { $status_info["attachments"] = $converted["attachments"]; @@ -1368,9 +1406,9 @@ function api_status_show($type) } if (($lastwall['item_network'] != "") && ($status["source"] == 'web')) { - $status_info["source"] = network_to_name($lastwall['item_network'], $user_info['url']); - } elseif (($lastwall['item_network'] != "") && (network_to_name($lastwall['item_network'], $user_info['url']) != $status_info["source"])) { - $status_info["source"] = trim($status_info["source"].' ('.network_to_name($lastwall['item_network'], $user_info['url']).')'); + $status_info["source"] = ContactSelector::networkToName($lastwall['item_network'], $user_info['url']); + } elseif (($lastwall['item_network'] != "") && (ContactSelector::networkToName($lastwall['item_network'], $user_info['url']) != $status_info["source"])) { + $status_info["source"] = trim($status_info["source"].' ('.ContactSelector::networkToName($lastwall['item_network'], $user_info['url']).')'); } // "uid" and "self" are only needed for some internal stuff, so remove it from here @@ -1384,13 +1422,15 @@ function api_status_show($type) return $status_info; } - return api_format_data("statuses", $type, array('status' => $status_info)); + return api_format_data("statuses", $type, ['status' => $status_info]); } /** * Returns extended information of a given user, specified by ID or screen name as per the required id parameter. * The author's most recent status will be returned inline. - * http://developer.twitter.com/doc/get/users/show + * + * @param string $type Return type (atom, rss, xml, json) + * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-show */ function api_users_show($type) { @@ -1429,7 +1469,7 @@ function api_users_show($type) $geo = "geo"; } - $user_info['status'] = array( + $user_info['status'] = [ 'text' => $converted["text"], 'truncated' => false, 'created_at' => api_date($lastwall['created']), @@ -1446,7 +1486,7 @@ function api_users_show($type) 'statusnet_html' => $converted["html"], 'statusnet_conversation_id' => $lastwall['parent'], 'external_url' => System::baseUrl() . "/display/" . $lastwall['guid'], - ); + ]; if (count($converted["attachments"]) > 0) { $user_info["status"]["attachments"] = $converted["attachments"]; @@ -1457,11 +1497,11 @@ function api_users_show($type) } if (($lastwall['item_network'] != "") && ($user_info["status"]["source"] == 'web')) { - $user_info["status"]["source"] = network_to_name($lastwall['item_network'], $user_info['url']); + $user_info["status"]["source"] = ContactSelector::networkToName($lastwall['item_network'], $user_info['url']); } - if (($lastwall['item_network'] != "") && (network_to_name($lastwall['item_network'], $user_info['url']) != $user_info["status"]["source"])) { - $user_info["status"]["source"] = trim($user_info["status"]["source"] . ' (' . network_to_name($lastwall['item_network'], $user_info['url']) . ')'); + if (($lastwall['item_network'] != "") && (ContactSelector::networkToName($lastwall['item_network'], $user_info['url']) != $user_info["status"]["source"])) { + $user_info["status"]["source"] = trim($user_info["status"]["source"] . ' (' . ContactSelector::networkToName($lastwall['item_network'], $user_info['url']) . ')'); } } @@ -1469,20 +1509,26 @@ function api_users_show($type) unset($user_info["uid"]); unset($user_info["self"]); - return api_format_data("user", $type, array('user' => $user_info)); + return api_format_data("user", $type, ['user' => $user_info]); } /// @TODO move to top of file or somewhere better api_register_func('api/users/show', 'api_users_show'); api_register_func('api/externalprofile/show', 'api_users_show'); +/** + * Search a public user account. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-search + */ function api_users_search($type) { $a = get_app(); - $page = (x($_REQUEST, 'page') ? $_REQUEST['page'] - 1 : 0); - - $userlist = array(); + $userlist = []; if (x($_GET, 'q')) { $r = q("SELECT id FROM `contact` WHERE `uid` = 0 AND `name` = '%s'", dbesc($_GET["q"])); @@ -1494,7 +1540,7 @@ function api_users_search($type) if (DBM::is_result($r)) { $k = 0; foreach ($r as $user) { - $user_info = api_get_user($a, $user["id"], "json"); + $user_info = api_get_user($a, $user["id"]); if ($type == "xml") { $userlist[$k++.":user"] = $user_info; @@ -1502,13 +1548,14 @@ function api_users_search($type) $userlist[] = $user_info; } } - $userlist = array("users" => $userlist); + $userlist = ["users" => $userlist]; } else { throw new BadRequestException("User not found."); } } else { throw new BadRequestException("User not found."); } + return api_format_data("users", $type, $userlist); } @@ -1527,7 +1574,7 @@ api_register_func('api/users/search', 'api_users_search'); */ function api_users_lookup($type) { - $users = array(); + $users = []; if (x($_REQUEST['user_id'])) { foreach (explode(',', $_REQUEST['user_id']) as $id) { @@ -1541,7 +1588,7 @@ function api_users_lookup($type) throw new NotFoundException; } - return api_format_data("users", $type, array('users' => $users)); + return api_format_data("users", $type, ['users' => $users]); } /// @TODO move to top of file or somewhere better @@ -1559,7 +1606,7 @@ api_register_func('api/users/lookup', 'api_users_lookup', true); */ function api_search($type) { - $data = array(); + $data = []; if (!x($_REQUEST, 'q')) { throw new BadRequestException("q parameter is required."); @@ -1606,11 +1653,14 @@ api_register_func('api/search/tweets', 'api_search', true); api_register_func('api/search', 'api_search', true); /** + * Returns the most recent statuses posted by the user and the users they follow. + * + * @see https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-home_timeline * - * http://developer.twitter.com/doc/get/statuses/home_timeline + * @param string $type Return type (atom, rss, xml, json) * - * TODO: Optional parameters - * TODO: Add reply info + * @todo Optional parameters + * @todo Add reply info */ function api_statuses_home_timeline($type) { @@ -1677,7 +1727,7 @@ function api_statuses_home_timeline($type) $ret = api_format_items($r, $user_info, false, $type); // Set all posts from the query above to seen - $idarray = array(); + $idarray = []; foreach ($r as $item) { $idarray[] = intval($item["id"]); } @@ -1688,11 +1738,11 @@ function api_statuses_home_timeline($type) $unseen = q("SELECT `id` FROM `item` WHERE `unseen` AND `id` IN (%s)", $idlist); if ($unseen) { - $r = q("UPDATE `item` SET `unseen` = 0 WHERE `unseen` AND `id` IN (%s)", $idlist); + q("UPDATE `item` SET `unseen` = 0 WHERE `unseen` AND `id` IN (%s)", $idlist); } } - $data = array('status' => $ret); + $data = ['status' => $ret]; switch ($type) { case "atom": case "rss": @@ -1707,6 +1757,13 @@ function api_statuses_home_timeline($type) api_register_func('api/statuses/home_timeline', 'api_statuses_home_timeline', true); api_register_func('api/statuses/friends_timeline', 'api_statuses_home_timeline', true); +/** + * Returns the most recent statuses from public users. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_statuses_public_timeline($type) { $a = get_app(); @@ -1737,7 +1794,8 @@ function api_statuses_public_timeline($type) $sql_extra = 'AND `thread`.`iid` <= ' . intval($max_id); } - $r = dba::p("SELECT " . item_fieldlists() . " + $r = dba::p( + "SELECT " . item_fieldlists() . " FROM `thread` STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid` " . item_joins() . " @@ -1766,7 +1824,8 @@ function api_statuses_public_timeline($type) $sql_extra .= ' AND `item`.`parent` = ' . intval($conversation_id); } - $r = dba::p("SELECT " . item_fieldlists() . " + $r = dba::p( + "SELECT " . item_fieldlists() . " FROM `item` " . item_joins() . " STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid` @@ -1790,7 +1849,7 @@ function api_statuses_public_timeline($type) $ret = api_format_items($r, $user_info, false, $type); - $data = array('status' => $ret); + $data = ['status' => $ret]; switch ($type) { case "atom": case "rss": @@ -1805,6 +1864,8 @@ function api_statuses_public_timeline($type) api_register_func('api/statuses/public_timeline', 'api_statuses_public_timeline', true); /** + * Returns the most recent statuses posted by users this node knows about. + * * @brief Returns the list of public federated posts this node knows about * * @param string $type Return format: json, xml, atom, rss @@ -1837,7 +1898,8 @@ function api_statuses_networkpublic_timeline($type) $sql_extra = 'AND `thread`.`iid` <= ' . intval($max_id); } - $r = dba::p("SELECT " . item_fieldlists() . " + $r = dba::p( + "SELECT " . item_fieldlists() . " FROM `thread` STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid` " . item_joins() . " @@ -1859,7 +1921,7 @@ function api_statuses_networkpublic_timeline($type) $ret = api_format_items($r, $user_info, false, $type); - $data = array('status' => $ret); + $data = ['status' => $ret]; switch ($type) { case "atom": case "rss": @@ -1874,7 +1936,11 @@ function api_statuses_networkpublic_timeline($type) api_register_func('api/statuses/networkpublic_timeline', 'api_statuses_networkpublic_timeline', true); /** - * @TODO nothing to say? + * Returns a single status. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @see https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-show-id */ function api_statuses_show($type) { @@ -1933,10 +1999,10 @@ function api_statuses_show($type) $ret = api_format_items($r, $user_info, false, $type); if ($conversation) { - $data = array('status' => $ret); + $data = ['status' => $ret]; return api_format_data("statuses", $type, $data); } else { - $data = array('status' => $ret[0]); + $data = ['status' => $ret[0]]; return api_format_data("status", $type, $data); } } @@ -1945,7 +2011,10 @@ function api_statuses_show($type) api_register_func('api/statuses/show', 'api_statuses_show', true); /** - * @TODO nothing to say? + * + * @param string $type Return type (atom, rss, xml, json) + * + * @todo nothing to say? */ function api_conversation_show($type) { @@ -2009,10 +2078,12 @@ function api_conversation_show($type) AND `item`.`uid` = %d AND `item`.`verb` = '%s' AND `item`.`id`>%d $sql_extra ORDER BY `item`.`id` DESC LIMIT %d ,%d", - intval($id), intval(api_user()), + intval($id), + intval(api_user()), dbesc(ACTIVITY_POST), intval($since_id), - intval($start), intval($count) + intval($start), + intval($count) ); if (!DBM::is_result($r)) { @@ -2021,7 +2092,7 @@ function api_conversation_show($type) $ret = api_format_items($r, $user_info, false, $type); - $data = array('status' => $ret); + $data = ['status' => $ret]; return api_format_data("statuses", $type, $data); } @@ -2030,7 +2101,11 @@ api_register_func('api/conversation/show', 'api_conversation_show', true); api_register_func('api/statusnet/conversation', 'api_conversation_show', true); /** - * @TODO nothing to say? + * Repeats a status. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @see https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-retweet-id */ function api_statuses_repeat($type) { @@ -2042,7 +2117,7 @@ function api_statuses_repeat($type) throw new ForbiddenException(); } - $user_info = api_get_user($a); + api_get_user($a); // params $id = intval($a->argv[3]); @@ -2108,7 +2183,11 @@ function api_statuses_repeat($type) api_register_func('api/statuses/retweet', 'api_statuses_repeat', true, API_METHOD_POST); /** - * @TODO nothing to say? + * Destroys a specific status. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @see https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-destroy-id */ function api_statuses_destroy($type) { @@ -2118,7 +2197,7 @@ function api_statuses_destroy($type) throw new ForbiddenException(); } - $user_info = api_get_user($a); + api_get_user($a); // params $id = intval($a->argv[3]); @@ -2136,7 +2215,7 @@ function api_statuses_destroy($type) $ret = api_statuses_show($type); - drop_item($id, false); + Item::delete($id); return $ret; } @@ -2145,8 +2224,11 @@ function api_statuses_destroy($type) api_register_func('api/statuses/destroy', 'api_statuses_destroy', true, API_METHOD_DELETE); /** - * @TODO Nothing more than an URL to say? - * http://developer.twitter.com/doc/get/statuses/mentions + * Returns the most recent mentions. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @see http://developer.twitter.com/doc/get/statuses/mentions */ function api_statuses_mentions($type) { @@ -2167,23 +2249,20 @@ function api_statuses_mentions($type) // params - $count = (x($_REQUEST, 'count') ? $_REQUEST['count'] : 20); - $page = (x($_REQUEST, 'page') ? $_REQUEST['page'] -1 : 0); - if ($page < 0) { - $page = 0; + $since_id = defaults($_REQUEST, 'since_id', 0); + $max_id = defaults($_REQUEST, 'max_id' , 0); + $count = defaults($_REQUEST, 'count' , 20); + $page = defaults($_REQUEST, 'page' , 1); + if ($page < 1) { + $page = 1; } - $since_id = (x($_REQUEST, 'since_id') ? $_REQUEST['since_id'] : 0); - $max_id = (x($_REQUEST, 'max_id') ? $_REQUEST['max_id'] : 0); - //$since_id = 0;//$since_id = (x($_REQUEST, 'since_id')?$_REQUEST['since_id'] : 0); - $start = $page * $count; + $start = ($page - 1) * $count; // Ugly code - should be changed $myurl = System::baseUrl() . '/profile/'. $a->user['nickname']; $myurl = substr($myurl, strpos($myurl, '://') + 3); - //$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl); $myurl = str_replace('www.', '', $myurl); - $diasp_url = str_replace('/profile/', '/u/', $myurl); if ($max_id > 0) { $sql_extra = ' AND `item`.`id` <= ' . intval($max_id); @@ -2216,7 +2295,7 @@ function api_statuses_mentions($type) $ret = api_format_items($r, $user_info, false, $type); - $data = array('status' => $ret); + $data = ['status' => $ret]; switch ($type) { case "atom": case "rss": @@ -2232,11 +2311,14 @@ api_register_func('api/statuses/mentions', 'api_statuses_mentions', true); api_register_func('api/statuses/replies', 'api_statuses_mentions', true); /** + * Returns the most recent statuses posted by the user. + * * @brief Returns a user's public timeline * * @param string $type Either "json" or "xml" * @return string|array * @throws ForbiddenException + * @see https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline */ function api_statuses_user_timeline($type) { @@ -2309,7 +2391,7 @@ function api_statuses_user_timeline($type) $ret = api_format_items($r, $user_info, true, $type); - $data = array('status' => $ret); + $data = ['status' => $ret]; switch ($type) { case "atom": case "rss": @@ -2320,14 +2402,16 @@ function api_statuses_user_timeline($type) return api_format_data("statuses", $type, $data); } -/// @TODO move to top of file or somwhere better -api_register_func('api/statuses/user_timeline','api_statuses_user_timeline', true); +/// @TODO move to top of file or somewhere better +api_register_func('api/statuses/user_timeline', 'api_statuses_user_timeline', true); /** - * Star/unstar an item + * Star/unstar an item. * param: id : id of the item * - * api v1 : https://web.archive.org/web/20131019055350/https://dev.twitter.com/docs/api/1/post/favorites/create/%3Aid + * @param string $type Return type (atom, rss, xml, json) + * + * @see https://web.archive.org/web/20131019055350/https://dev.twitter.com/docs/api/1/post/favorites/create/%3Aid */ function api_favorites_create_destroy($type) { @@ -2372,7 +2456,7 @@ function api_favorites_create_destroy($type) throw new BadRequestException("Invalid action ".$action); } - $r = q("UPDATE item SET starred=%d WHERE id=%d AND uid=%d", $item[0]['starred'], $itemid, api_user()); + $r = q("UPDATE item SET starred=%d WHERE id=%d AND uid=%d", $item[0]['starred'], $itemid, api_user()); q("UPDATE thread SET starred=%d WHERE iid=%d AND uid=%d", $item[0]['starred'], $itemid, api_user()); @@ -2385,7 +2469,7 @@ function api_favorites_create_destroy($type) $rets = api_format_items($item, $user_info, false, $type); $ret = $rets[0]; - $data = array('status' => $ret); + $data = ['status' => $ret]; switch ($type) { case "atom": case "rss": @@ -2395,10 +2479,17 @@ function api_favorites_create_destroy($type) return api_format_data("status", $type, $data); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/favorites/create', 'api_favorites_create_destroy', true, API_METHOD_POST); api_register_func('api/favorites/destroy', 'api_favorites_create_destroy', true, API_METHOD_DELETE); +/** + * Returns the most recent favorite statuses. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return string|array + */ function api_favorites($type) { global $called_api; @@ -2409,7 +2500,7 @@ function api_favorites($type) throw new ForbiddenException(); } - $called_api = array(); + $called_api = []; $user_info = api_get_user($a); @@ -2418,7 +2509,7 @@ function api_favorites($type) logger('api_favorites: self:' . $user_info['self']); if ($user_info['self'] == 0) { - $ret = array(); + $ret = []; } else { $sql_extra = ""; @@ -2460,7 +2551,7 @@ function api_favorites($type) $ret = api_format_items($r, $user_info, false, $type); } - $data = array('status' => $ret); + $data = ['status' => $ret]; switch ($type) { case "atom": case "rss": @@ -2470,13 +2561,21 @@ function api_favorites($type) return api_format_data("statuses", $type, $data); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/favorites', 'api_favorites', true); +/** + * + * @param array $item + * @param array $recipient + * @param array $sender + * + * @return array + */ function api_format_messages($item, $recipient, $sender) { // standard meta information - $ret = array( + $ret = [ 'id' => $item['id'], 'sender_id' => $sender['id'] , 'text' => "", @@ -2489,7 +2588,7 @@ function api_format_messages($item, $recipient, $sender) 'title' => "", 'friendica_seen' => $item['seen'], 'friendica_parent_uri' => $item['parent-uri'], - ); + ]; // "uid" and "self" are only needed for some internal stuff, so remove it from here unset($ret["sender"]["uid"]); @@ -2517,6 +2616,12 @@ function api_format_messages($item, $recipient, $sender) return $ret; } +/** + * + * @param array $item + * + * @return array + */ function api_convert_item($item) { $body = $item['body']; @@ -2544,14 +2649,14 @@ function api_convert_item($item) $statushtml = trim(bbcode($body, false, false)); // Workaround for clients with limited HTML parser functionality - $search = array("
", "
", "
", + $search = ["
", "
", "
", "

", "

", "

", "

", "

", "

", "

", "

", - "
", "
", "
", "
"); - $replace = array("
", "
", "

", + "
", "
", "
", "
"]; + $replace = ["
", "
", "

", "

", "


", "

", "


", "

", "


", "

", "


", - "
", "

", "
", "

"); + "
", "

", "
", "

"]; $statushtml = str_replace($search, $replace, $statushtml); if ($item['title'] != "") { @@ -2578,14 +2683,20 @@ function api_convert_item($item) $entities = api_get_entitities($statustext, $body); - return array( + return [ "text" => $statustext, "html" => $statushtml, "attachments" => $attachments, "entities" => $entities - ); + ]; } +/** + * + * @param string $body + * + * @return array|false + */ function api_get_attachments(&$body) { $text = $body; @@ -2598,13 +2709,13 @@ function api_get_attachments(&$body) return false; } - $attachments = array(); + $attachments = []; foreach ($images[1] as $image) { $imagedata = Image::getInfoFromURL($image); if ($imagedata) { - $attachments[] = array("url" => $image, "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]); + $attachments[] = ["url" => $image, "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]]; } } @@ -2617,15 +2728,16 @@ function api_get_attachments(&$body) return $attachments; } +/** + * + * @param string $text + * @param string $bbcode + * + * @return array + * @todo Links at the first character of the post + */ function api_get_entitities(&$text, $bbcode) { - /* - To-Do: - * Links at the first character of the post - */ - - $a = get_app(); - $include_entities = strtolower(x($_REQUEST, 'include_entities') ? $_REQUEST['include_entities'] : "false"); if ($include_entities != "true") { @@ -2635,7 +2747,7 @@ function api_get_entitities(&$text, $bbcode) $replace = proxy_url($image); $text = str_replace($image, $replace, $text); } - return array(); + return []; } $bbcode = bb_CleanPictureLinks($bbcode); @@ -2643,11 +2755,11 @@ function api_get_entitities(&$text, $bbcode) // Change pure links in text to bbcode uris $bbcode = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url=$2]$2[/url]', $bbcode); - $entities = array(); - $entities["hashtags"] = array(); - $entities["symbols"] = array(); - $entities["urls"] = array(); - $entities["user_mentions"] = array(); + $entities = []; + $entities["hashtags"] = []; + $entities["symbols"] = []; + $entities["urls"] = []; + $entities["user_mentions"] = []; $URLSearchString = "^\[\]"; @@ -2676,12 +2788,12 @@ function api_get_entitities(&$text, $bbcode) //preg_match_all("/\[url\]([$URLSearchString]*)\[\/url\]/ism", $bbcode, $urls1); preg_match_all("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", $bbcode, $urls); - $ordered_urls = array(); + $ordered_urls = []; foreach ($urls[1] as $id => $url) { //$start = strpos($text, $url, $offset); $start = iconv_strpos($text, $url, 0, "UTF-8"); if (!($start === false)) { - $ordered_urls[$start] = array("url" => $url, "title" => $urls[2][$id]); + $ordered_urls[$start] = ["url" => $url, "title" => $urls[2][$id]]; } } @@ -2692,44 +2804,47 @@ function api_get_entitities(&$text, $bbcode) foreach ($ordered_urls as $url) { if ((substr($url["title"], 0, 7) != "http://") && (substr($url["title"], 0, 8) != "https://") && !strpos($url["title"], "http://") && !strpos($url["title"], "https://") - ) + ) { $display_url = $url["title"]; - else { - $display_url = str_replace(array("http://www.", "https://www."), array("", ""), $url["url"]); - $display_url = str_replace(array("http://", "https://"), array("", ""), $display_url); + } else { + $display_url = str_replace(["http://www.", "https://www."], ["", ""], $url["url"]); + $display_url = str_replace(["http://", "https://"], ["", ""], $display_url); - if (strlen($display_url) > 26) + if (strlen($display_url) > 26) { $display_url = substr($display_url, 0, 25)."…"; + } } //$start = strpos($text, $url, $offset); $start = iconv_strpos($text, $url["url"], $offset, "UTF-8"); if (!($start === false)) { - $entities["urls"][] = array("url" => $url["url"], + $entities["urls"][] = ["url" => $url["url"], "expanded_url" => $url["url"], "display_url" => $display_url, - "indices" => array($start, $start+strlen($url["url"]))); + "indices" => [$start, $start+strlen($url["url"])]]; $offset = $start + 1; } } preg_match_all("/\[img](.*?)\[\/img\]/ism", $bbcode, $images); - $ordered_images = array(); + $ordered_images = []; foreach ($images[1] as $image) { //$start = strpos($text, $url, $offset); $start = iconv_strpos($text, $image, 0, "UTF-8"); - if (!($start === false)) + if (!($start === false)) { $ordered_images[$start] = $image; + } } //$entities["media"] = array(); $offset = 0; foreach ($ordered_images as $url) { - $display_url = str_replace(array("http://www.", "https://www."), array("", ""), $url); - $display_url = str_replace(array("http://", "https://"), array("", ""), $display_url); + $display_url = str_replace(["http://www.", "https://www."], ["", ""], $url); + $display_url = str_replace(["http://", "https://"], ["", ""], $display_url); - if (strlen($display_url) > 26) + if (strlen($display_url) > 26) { $display_url = substr($display_url, 0, 25)."…"; + } $start = iconv_strpos($text, $url, $offset, "UTF-8"); if (!($start === false)) { @@ -2740,38 +2855,38 @@ function api_get_entitities(&$text, $bbcode) if (!Config::get("system", "proxy_disabled")) { $media_url = proxy_url($url); - $sizes = array(); + $sizes = []; $scale = Image::getScalingDimensions($image[0], $image[1], 150); - $sizes["thumb"] = array("w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"); + $sizes["thumb"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; if (($image[0] > 150) || ($image[1] > 150)) { $scale = Image::getScalingDimensions($image[0], $image[1], 340); - $sizes["small"] = array("w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"); + $sizes["small"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; } $scale = Image::getScalingDimensions($image[0], $image[1], 600); - $sizes["medium"] = array("w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"); + $sizes["medium"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; if (($image[0] > 600) || ($image[1] > 600)) { $scale = Image::getScalingDimensions($image[0], $image[1], 1024); - $sizes["large"] = array("w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"); + $sizes["large"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; } } else { $media_url = $url; - $sizes["medium"] = array("w" => $image[0], "h" => $image[1], "resize" => "fit"); + $sizes["medium"] = ["w" => $image[0], "h" => $image[1], "resize" => "fit"]; } - $entities["media"][] = array( + $entities["media"][] = [ "id" => $start+1, "id_str" => (string)$start+1, - "indices" => array($start, $start+strlen($url)), + "indices" => [$start, $start+strlen($url)], "media_url" => normalise_link($media_url), "media_url_https" => $media_url, "url" => $url, "display_url" => $display_url, "expanded_url" => $url, "type" => "photo", - "sizes" => $sizes); + "sizes" => $sizes]; } $offset = $start + 1; } @@ -2779,41 +2894,48 @@ function api_get_entitities(&$text, $bbcode) return $entities; } -function api_format_items_embeded_images(&$item, $text) + +/** + * + * @param array $item + * @param string $text + * + * @return string + */ +function api_format_items_embeded_images($item, $text) { $text = preg_replace_callback( - "|data:image/([^;]+)[^=]+=*|m", - function ($match) use ($item) { - return System::baseUrl()."/display/".$item['guid']; + '|data:image/([^;]+)[^=]+=*|m', + function () use ($item) { + return System::baseUrl() . '/display/' . $item['guid']; }, $text ); return $text; } - /** * @brief return name as array * * @param string $txt text * @return array - * name => 'name' + * 'name' => 'name', * 'url => 'url' */ function api_contactlink_to_array($txt) { - $match = array(); + $match = []; $r = preg_match_all('|([^<]*)|', $txt, $match); if ($r && count($match)==3) { - $res = array( + $res = [ 'name' => $match[2], 'url' => $match[1] - ); + ]; } else { - $res = array( + $res = [ 'name' => $text, 'url' => "" - ); + ]; } return $res; } @@ -2823,21 +2945,23 @@ function api_contactlink_to_array($txt) * @brief return likes, dislikes and attend status for item * * @param array $item array + * @param string $type Return type (atom, rss, xml, json) + * * @return array - * likes => int count + * likes => int count, * dislikes => int count */ function api_format_items_activities(&$item, $type = "json") { $a = get_app(); - $activities = array( - 'like' => array(), - 'dislike' => array(), - 'attendyes' => array(), - 'attendno' => array(), - 'attendmaybe' => array(), - ); + $activities = [ + 'like' => [], + 'dislike' => [], + 'attendyes' => [], + 'attendno' => [], + 'attendmaybe' => [], + ]; $items = q( 'SELECT * FROM item @@ -2874,14 +2998,15 @@ function api_format_items_activities(&$item, $type = "json") } if ($type == "xml") { - $xml_activities = array(); + $xml_activities = []; foreach ($activities as $k => $v) { // change xml element from "like" to "friendica:like" $xml_activities["friendica:".$k] = $v; // add user data into xml output $k_user = 0; - foreach ($v as $user) + foreach ($v as $user) { $xml_activities["friendica:".$k][$k_user++.":user"] = $user; + } } $activities = $xml_activities; } @@ -2893,68 +3018,68 @@ function api_format_items_activities(&$item, $type = "json") /** * @brief return data from profiles * - * @param array $profile array containing data from db table 'profile' - * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * @param array $profile_row array containing data from db table 'profile' * @return array */ -function api_format_items_profiles(&$profile = null, $type = "json") +function api_format_items_profiles($profile_row) { - if ($profile != null) { - $profile = array('profile_id' => $profile['id'], - 'profile_name' => $profile['profile-name'], - 'is_default' => $profile['is-default'] ? true : false, - 'hide_friends'=> $profile['hide-friends'] ? true : false, - 'profile_photo' => $profile['photo'], - 'profile_thumb' => $profile['thumb'], - 'publish' => $profile['publish'] ? true : false, - 'net_publish' => $profile['net-publish'] ? true : false, - 'description' => $profile['pdesc'], - 'date_of_birth' => $profile['dob'], - 'address' => $profile['address'], - 'city' => $profile['locality'], - 'region' => $profile['region'], - 'postal_code' => $profile['postal-code'], - 'country' => $profile['country-name'], - 'hometown' => $profile['hometown'], - 'gender' => $profile['gender'], - 'marital' => $profile['marital'], - 'marital_with' => $profile['with'], - 'marital_since' => $profile['howlong'], - 'sexual' => $profile['sexual'], - 'politic' => $profile['politic'], - 'religion' => $profile['religion'], - 'public_keywords' => $profile['pub_keywords'], - 'private_keywords' => $profile['prv_keywords'], - 'likes' => bbcode(api_clean_plain_items($profile['likes']), false, false, 2, false), - 'dislikes' => bbcode(api_clean_plain_items($profile['dislikes']), false, false, 2, false), - 'about' => bbcode(api_clean_plain_items($profile['about']), false, false, 2, false), - 'music' => bbcode(api_clean_plain_items($profile['music']), false, false, 2, false), - 'book' => bbcode(api_clean_plain_items($profile['book']), false, false, 2, false), - 'tv' => bbcode(api_clean_plain_items($profile['tv']), false, false, 2, false), - 'film' => bbcode(api_clean_plain_items($profile['film']), false, false, 2, false), - 'interest' => bbcode(api_clean_plain_items($profile['interest']), false, false, 2, false), - 'romance' => bbcode(api_clean_plain_items($profile['romance']), false, false, 2, false), - 'work' => bbcode(api_clean_plain_items($profile['work']), false, false, 2, false), - 'education' => bbcode(api_clean_plain_items($profile['education']), false, false, 2, false), - 'social_networks' => bbcode(api_clean_plain_items($profile['contact']), false, false, 2, false), - 'homepage' => $profile['homepage'], - 'users' => null); - return $profile; - } + $profile = [ + 'profile_id' => $profile_row['id'], + 'profile_name' => $profile_row['profile-name'], + 'is_default' => $profile_row['is-default'] ? true : false, + 'hide_friends' => $profile_row['hide-friends'] ? true : false, + 'profile_photo' => $profile_row['photo'], + 'profile_thumb' => $profile_row['thumb'], + 'publish' => $profile_row['publish'] ? true : false, + 'net_publish' => $profile_row['net-publish'] ? true : false, + 'description' => $profile_row['pdesc'], + 'date_of_birth' => $profile_row['dob'], + 'address' => $profile_row['address'], + 'city' => $profile_row['locality'], + 'region' => $profile_row['region'], + 'postal_code' => $profile_row['postal-code'], + 'country' => $profile_row['country-name'], + 'hometown' => $profile_row['hometown'], + 'gender' => $profile_row['gender'], + 'marital' => $profile_row['marital'], + 'marital_with' => $profile_row['with'], + 'marital_since' => $profile_row['howlong'], + 'sexual' => $profile_row['sexual'], + 'politic' => $profile_row['politic'], + 'religion' => $profile_row['religion'], + 'public_keywords' => $profile_row['pub_keywords'], + 'private_keywords' => $profile_row['prv_keywords'], + 'likes' => bbcode(api_clean_plain_items($profile_row['likes']) , false, false, 2, false), + 'dislikes' => bbcode(api_clean_plain_items($profile_row['dislikes']) , false, false, 2, false), + 'about' => bbcode(api_clean_plain_items($profile_row['about']) , false, false, 2, false), + 'music' => bbcode(api_clean_plain_items($profile_row['music']) , false, false, 2, false), + 'book' => bbcode(api_clean_plain_items($profile_row['book']) , false, false, 2, false), + 'tv' => bbcode(api_clean_plain_items($profile_row['tv']) , false, false, 2, false), + 'film' => bbcode(api_clean_plain_items($profile_row['film']) , false, false, 2, false), + 'interest' => bbcode(api_clean_plain_items($profile_row['interest']) , false, false, 2, false), + 'romance' => bbcode(api_clean_plain_items($profile_row['romance']) , false, false, 2, false), + 'work' => bbcode(api_clean_plain_items($profile_row['work']) , false, false, 2, false), + 'education' => bbcode(api_clean_plain_items($profile_row['education']), false, false, 2, false), + 'social_networks' => bbcode(api_clean_plain_items($profile_row['contact']) , false, false, 2, false), + 'homepage' => $profile_row['homepage'], + 'users' => null + ]; + return $profile; } /** * @brief format items to be returned by api * - * @param array $r array of items - * @param array $user_info - * @param bool $filter_user filter items by $user_info + * @param array $r array of items + * @param array $user_info + * @param bool $filter_user filter items by $user_info + * @param string $type Return type (atom, rss, xml, json) */ function api_format_items($r, $user_info, $filter_user = false, $type = "json") { $a = get_app(); - $ret = array(); + $ret = []; foreach ($r as $item) { localize_item($item); @@ -2975,7 +3100,7 @@ function api_format_items($r, $user_info, $filter_user = false, $type = "json") $geo = "geo"; } - $status = array( + $status = [ 'text' => $converted["text"], 'truncated' => false, 'created_at'=> api_date($item['created']), @@ -2996,7 +3121,7 @@ function api_format_items($r, $user_info, $filter_user = false, $type = "json") 'statusnet_conversation_id' => $item['parent'], 'external_url' => System::baseUrl() . "/display/" . $item['guid'], 'friendica_activities' => api_format_items_activities($item, $type), - ); + ]; if (count($converted["attachments"]) > 0) { $status["attachments"] = $converted["attachments"]; @@ -3007,9 +3132,9 @@ function api_format_items($r, $user_info, $filter_user = false, $type = "json") } if (($item['item_network'] != "") && ($status["source"] == 'web')) { - $status["source"] = network_to_name($item['item_network'], $user_info['url']); - } elseif (($item['item_network'] != "") && (network_to_name($item['item_network'], $user_info['url']) != $status["source"])) { - $status["source"] = trim($status["source"].' ('.network_to_name($item['item_network'], $user_info['url']).')'); + $status["source"] = ContactSelector::networkToName($item['item_network'], $user_info['url']); + } elseif (($item['item_network'] != "") && (ContactSelector::networkToName($item['item_network'], $user_info['url']) != $status["source"])) { + $status["source"] = trim($status["source"].' ('.ContactSelector::networkToName($item['item_network'], $user_info['url']).')'); } @@ -3029,7 +3154,7 @@ function api_format_items($r, $user_info, $filter_user = false, $type = "json") } catch (BadRequestException $e) { // user not found. should be found? /// @todo check if the user should be always found - $retweeted_status["user"] = array(); + $retweeted_status["user"] = []; } $rt_converted = api_convert_item($retweeted_item); @@ -3049,12 +3174,13 @@ function api_format_items($r, $user_info, $filter_user = false, $type = "json") if ($item["coord"] != "") { $coords = explode(' ', $item["coord"]); if (count($coords) == 2) { - if ($type == "json") - $status["geo"] = array('type' => 'Point', - 'coordinates' => array((float) $coords[0], - (float) $coords[1])); - else // Not sure if this is the official format - if someone founds a documentation we can check + if ($type == "json") { + $status["geo"] = ['type' => 'Point', + 'coordinates' => [(float) $coords[0], + (float) $coords[1]]]; + } else {// Not sure if this is the official format - if someone founds a documentation we can check $status["georss:point"] = $item["coord"]; + } } } $ret[] = $status; @@ -3062,34 +3188,48 @@ function api_format_items($r, $user_info, $filter_user = false, $type = "json") return $ret; } +/** + * Returns the remaining number of API requests available to the user before the API limit is reached. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_account_rate_limit_status($type) { if ($type == "xml") { - $hash = array( + $hash = [ 'remaining-hits' => '150', - '@attributes' => array("type" => "integer"), + '@attributes' => ["type" => "integer"], 'hourly-limit' => '150', - '@attributes2' => array("type" => "integer"), + '@attributes2' => ["type" => "integer"], 'reset-time' => datetime_convert('UTC', 'UTC', 'now + 1 hour', ATOM_TIME), - '@attributes3' => array("type" => "datetime"), + '@attributes3' => ["type" => "datetime"], 'reset_time_in_seconds' => strtotime('now + 1 hour'), - '@attributes4' => array("type" => "integer"), - ); + '@attributes4' => ["type" => "integer"], + ]; } else { - $hash = array( + $hash = [ 'reset_time_in_seconds' => strtotime('now + 1 hour'), 'remaining_hits' => '150', 'hourly_limit' => '150', 'reset_time' => api_date(datetime_convert('UTC', 'UTC', 'now + 1 hour', ATOM_TIME)), - ); + ]; } - return api_format_data('hash', $type, array('hash' => $hash)); + return api_format_data('hash', $type, ['hash' => $hash]); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/account/rate_limit_status', 'api_account_rate_limit_status', true); +/** + * Returns the string "ok" in the requested format with a 200 OK HTTP status code. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_help_test($type) { if ($type == 'xml') { @@ -3098,38 +3238,52 @@ function api_help_test($type) $ok = "ok"; } - return api_format_data('ok', $type, array("ok" => $ok)); + return api_format_data('ok', $type, ["ok" => $ok]); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/help/test', 'api_help_test', false); +/** + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_lists($type) { - $ret = array(); + $ret = []; /// @TODO $ret is not filled here? - return api_format_data('lists', $type, array("lists_list" => $ret)); + return api_format_data('lists', $type, ["lists_list" => $ret]); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/lists', 'api_lists', true); +/** + * Returns all lists the user subscribes to. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + * @see https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-list + */ function api_lists_list($type) { - $ret = array(); + $ret = []; /// @TODO $ret is not filled here? - return api_format_data('lists', $type, array("lists_list" => $ret)); + return api_format_data('lists', $type, ["lists_list" => $ret]); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/lists/list', 'api_lists_list', true); /** - * @brief Returns either the friends of the follower list - * - * Note: Considers friends and followers lists to be private and won't return + * Considers friends and followers lists to be private and won't return * anything if any user_id parameter is passed. * + * @brief Returns either the friends of the follower list + * * @param string $qtype Either "friends" or "followers" * @return boolean|array * @throws ForbiddenException @@ -3163,10 +3317,10 @@ function api_statuses_f($qtype) return false; } + $sql_extra = ''; if ($qtype == 'friends') { $sql_extra = sprintf(" AND ( `rel` = %d OR `rel` = %d ) ", intval(CONTACT_IS_SHARING), intval(CONTACT_IS_FRIEND)); - } - if ($qtype == 'followers') { + } elseif ($qtype == 'followers') { $sql_extra = sprintf(" AND ( `rel` = %d OR `rel` = %d ) ", intval(CONTACT_IS_FOLLOWER), intval(CONTACT_IS_FRIEND)); } @@ -3197,7 +3351,7 @@ function api_statuses_f($qtype) intval($count) ); - $ret = array(); + $ret = []; foreach ($r as $cid) { $user = api_get_user($a, $cid['nurl']); // "uid" and "self" are only needed for some internal stuff, so remove it from here @@ -3209,11 +3363,13 @@ function api_statuses_f($qtype) } } - return array('user' => $ret); + return ['user' => $ret]; } /** + * Returns the user's friends. + * * @brief Returns the list of friends of the provided user * * @deprecated By Twitter API in favor of friends/list @@ -3231,7 +3387,9 @@ function api_statuses_friends($type) } /** - * @brief Returns the list of friends of the provided user + * Returns the user's followers. + * + * @brief Returns the list of followers of the provided user * * @deprecated By Twitter API in favor of friends/list * @@ -3288,17 +3446,24 @@ function api_friendships_incoming($type) return false; } - $ids = array(); + $ids = []; foreach ($data['user'] as $user) { $ids[] = $user['id']; } - return api_format_data("ids", $type, array('id' => $ids)); + return api_format_data("ids", $type, ['id' => $ids]); } /// @TODO move to top of file or somewhere better api_register_func('api/friendships/incoming', 'api_friendships_incoming', true); +/** + * Returns the instance's configuration information. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_statusnet_config($type) { $a = get_app(); @@ -3311,39 +3476,45 @@ function api_statusnet_config($type) $private = ((Config::get('system', 'block_public')) ? 'true' : 'false'); $textlimit = (string) (($a->config['max_import_size']) ? $a->config['max_import_size'] : 200000); if ($a->config['api_import_size']) { - $texlimit = string($a->config['api_import_size']); + $textlimit = (string) $a->config['api_import_size']; } $ssl = ((Config::get('system', 'have_ssl')) ? 'true' : 'false'); $sslserver = (($ssl === 'true') ? str_replace('http:', 'https:', System::baseUrl()) : ''); - $config = array( - 'site' => array('name' => $name,'server' => $server, 'theme' => 'default', 'path' => '', + $config = [ + 'site' => ['name' => $name,'server' => $server, 'theme' => 'default', 'path' => '', 'logo' => $logo, 'fancy' => true, 'language' => 'en', 'email' => $email, 'broughtby' => '', 'broughtbyurl' => '', 'timezone' => 'UTC', 'closed' => $closed, 'inviteonly' => false, 'private' => $private, 'textlimit' => $textlimit, 'sslserver' => $sslserver, 'ssl' => $ssl, 'shorturllength' => '30', - 'friendica' => array( + 'friendica' => [ 'FRIENDICA_PLATFORM' => FRIENDICA_PLATFORM, 'FRIENDICA_VERSION' => FRIENDICA_VERSION, 'DFRN_PROTOCOL_VERSION' => DFRN_PROTOCOL_VERSION, 'DB_UPDATE_VERSION' => DB_UPDATE_VERSION - ) - ), - ); + ] + ], + ]; - return api_format_data('config', $type, array('config' => $config)); + return api_format_data('config', $type, ['config' => $config]); } /// @TODO move to top of file or somewhere better api_register_func('api/gnusocial/config', 'api_statusnet_config', false); api_register_func('api/statusnet/config', 'api_statusnet_config', false); +/** + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_statusnet_version($type) { // liar $fake_statusnet_version = "0.9.7"; - return api_format_data('version', $type, array('version' => $fake_statusnet_version)); + return api_format_data('version', $type, ['version' => $fake_statusnet_version]); } /// @TODO move to top of file or somewhere better @@ -3351,30 +3522,20 @@ api_register_func('api/gnusocial/version', 'api_statusnet_version', false); api_register_func('api/statusnet/version', 'api_statusnet_version', false); /** + * + * @param string $type Return type (atom, rss, xml, json) + * * @todo use api_format_data() to return data */ -function api_ff_ids($type,$qtype) +function api_ff_ids($type) { - $a = get_app(); - if (! api_user()) { throw new ForbiddenException(); } - $user_info = api_get_user($a); + api_get_user($a); - if ($qtype == 'friends') { - $sql_extra = sprintf(" AND ( `rel` = %d OR `rel` = %d ) ", intval(CONTACT_IS_SHARING), intval(CONTACT_IS_FRIEND)); - } - if ($qtype == 'followers') { - $sql_extra = sprintf(" AND ( `rel` = %d OR `rel` = %d ) ", intval(CONTACT_IS_FOLLOWER), intval(CONTACT_IS_FRIEND)); - } - - if (!$user_info["self"]) { - $sql_extra = " AND false "; - } - - $stringify_ids = (x($_REQUEST, 'stringify_ids') ? $_REQUEST['stringify_ids'] : false); + $stringify_ids = defaults($_REQUEST, 'stringify_ids', false); $r = q( "SELECT `pcontact`.`id` FROM `contact` @@ -3382,12 +3543,11 @@ function api_ff_ids($type,$qtype) WHERE `contact`.`uid` = %s AND NOT `contact`.`self`", intval(api_user()) ); - if (!DBM::is_result($r)) { return; } - $ids = array(); + $ids = []; foreach ($r as $rr) { if ($stringify_ids) { $ids[] = $rr['id']; @@ -3396,31 +3556,59 @@ function api_ff_ids($type,$qtype) } } - return api_format_data("ids", $type, array('id' => $ids)); + return api_format_data("ids", $type, ['id' => $ids]); } +/** + * Returns the ID of every user the user is following. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids + */ function api_friends_ids($type) { - return api_ff_ids($type, 'friends'); + return api_ff_ids($type); } +/** + * Returns the ID of every user following the user. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids + */ function api_followers_ids($type) { - return api_ff_ids($type, 'followers'); + return api_ff_ids($type); } /// @TODO move to top of file or somewhere better api_register_func('api/friends/ids', 'api_friends_ids', true); api_register_func('api/followers/ids', 'api_followers_ids', true); +/** + * Sends a new direct message. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + * @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-message + */ function api_direct_messages_new($type) { $a = get_app(); - if (api_user() === false) throw new ForbiddenException(); + if (api_user() === false) { + throw new ForbiddenException(); + } - if (!x($_POST, "text") || (!x($_POST, "screen_name") && !x($_POST, "user_id"))) return; + if (!x($_POST, "text") || (!x($_POST, "screen_name") && !x($_POST, "user_id"))) { + return; + } $sender = api_get_user($a); @@ -3457,16 +3645,16 @@ function api_direct_messages_new($type) } } - $id = send_message($recipient['cid'], $_POST['text'], $sub, $replyto); + $id = Mail::send($recipient['cid'], $_POST['text'], $sub, $replyto); if ($id > -1) { $r = q("SELECT * FROM `mail` WHERE id=%d", intval($id)); $ret = api_format_messages($r[0], $recipient, $sender); } else { - $ret = array("error"=>$id); + $ret = ["error"=>$id]; } - $data = array('direct_message'=>$ret); + $data = ['direct_message'=>$ret]; switch ($type) { case "atom": @@ -3475,17 +3663,19 @@ function api_direct_messages_new($type) } return api_format_data("direct-messages", $type, $data); - } /// @TODO move to top of file or somewhere better api_register_func('api/direct_messages/new', 'api_direct_messages_new', true, API_METHOD_POST); /** + * Destroys a direct message. + * * @brief delete a direct_message from mail table through api * * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' * @return string + * @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/delete-message */ function api_direct_messages_destroy($type) { @@ -3507,8 +3697,8 @@ function api_direct_messages_destroy($type) $uid = $user_info['uid']; // error if no id or parenturi specified (for clients posting parent-uri as well) if ($verbose == "true" && ($id == 0 || $parenturi == "")) { - $answer = array('result' => 'error', 'message' => 'message id or parenturi not specified'); - return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); + $answer = ['result' => 'error', 'message' => 'message id or parenturi not specified']; + return api_format_data("direct_messages_delete", $type, ['$result' => $answer]); } // BadRequestException if no id specified (for clients using Twitter API) @@ -3529,8 +3719,8 @@ function api_direct_messages_destroy($type) // error message if specified id is not in database if (!DBM::is_result($r)) { if ($verbose == "true") { - $answer = array('result' => 'error', 'message' => 'message id not in database'); - return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); + $answer = ['result' => 'error', 'message' => 'message id not in database']; + return api_format_data("direct_messages_delete", $type, ['$result' => $answer]); } /// @todo BadRequestException ok for Twitter API clients? throw new BadRequestException('message id not in database'); @@ -3546,20 +3736,27 @@ function api_direct_messages_destroy($type) if ($verbose == "true") { if ($result) { // return success - $answer = array('result' => 'ok', 'message' => 'message deleted'); - return api_format_data("direct_message_delete", $type, array('$result' => $answer)); + $answer = ['result' => 'ok', 'message' => 'message deleted']; + return api_format_data("direct_message_delete", $type, ['$result' => $answer]); } else { - $answer = array('result' => 'error', 'message' => 'unknown error'); - return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); + $answer = ['result' => 'error', 'message' => 'unknown error']; + return api_format_data("direct_messages_delete", $type, ['$result' => $answer]); } } /// @todo return JSON data like Twitter API not yet implemented - } /// @TODO move to top of file or somewhere better api_register_func('api/direct_messages/destroy', 'api_direct_messages_destroy', true, API_METHOD_DELETE); +/** + * + * @param string $type Return type (atom, rss, xml, json) + * @param string $box + * @param string $verbose + * + * @return array|string + */ function api_direct_messages_box($type, $box, $verbose) { $a = get_app(); @@ -3623,11 +3820,11 @@ function api_direct_messages_box($type, $box, $verbose) intval($count) ); if ($verbose == "true" && !DBM::is_result($r)) { - $answer = array('result' => 'error', 'message' => 'no mails available'); - return api_format_data("direct_messages_all", $type, array('$result' => $answer)); + $answer = ['result' => 'error', 'message' => 'no mails available']; + return api_format_data("direct_messages_all", $type, ['$result' => $answer]); } - $ret = array(); + $ret = []; foreach ($r as $item) { if ($box == "inbox" || $item['from-url'] != $profile_url) { $recipient = $user_info; @@ -3641,7 +3838,7 @@ function api_direct_messages_box($type, $box, $verbose) } - $data = array('direct_message' => $ret); + $data = ['direct_message' => $ret]; switch ($type) { case "atom": case "rss": @@ -3651,24 +3848,52 @@ function api_direct_messages_box($type, $box, $verbose) return api_format_data("direct-messages", $type, $data); } +/** + * Returns the most recent direct messages sent by the user. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + * @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-sent-message + */ function api_direct_messages_sentbox($type) { $verbose = (x($_GET, 'friendica_verbose') ? strtolower($_GET['friendica_verbose']) : "false"); return api_direct_messages_box($type, "sentbox", $verbose); } +/** + * Returns the most recent direct messages sent to the user. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + * @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-messages + */ function api_direct_messages_inbox($type) { $verbose = (x($_GET, 'friendica_verbose') ? strtolower($_GET['friendica_verbose']) : "false"); return api_direct_messages_box($type, "inbox", $verbose); } +/** + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_direct_messages_all($type) { $verbose = (x($_GET, 'friendica_verbose') ? strtolower($_GET['friendica_verbose']) : "false"); return api_direct_messages_box($type, "all", $verbose); } +/** + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_direct_messages_conversation($type) { $verbose = (x($_GET, 'friendica_verbose') ? strtolower($_GET['friendica_verbose']) : "false"); @@ -3681,7 +3906,12 @@ api_register_func('api/direct_messages/all', 'api_direct_messages_all', true); api_register_func('api/direct_messages/sent', 'api_direct_messages_sentbox', true); api_register_func('api/direct_messages', 'api_direct_messages_inbox', true); -function api_oauth_request_token($type) +/** + * Returns an OAuth Request Token. + * + * @see https://oauth.net/core/1.0/#auth_step1 + */ +function api_oauth_request_token() { $oauth1 = new FKOAuth1(); try { @@ -3694,7 +3924,13 @@ function api_oauth_request_token($type) killme(); } -function api_oauth_access_token($type) +/** + * Returns an OAuth Access Token. + * + * @return array|string + * @see https://oauth.net/core/1.0/#auth_step3 + */ +function api_oauth_access_token() { $oauth1 = new FKOAuth1(); try { @@ -3736,8 +3972,9 @@ function api_fr_photoalbum_delete($type) intval(api_user()), dbesc($album) ); - if (!DBM::is_result($r)) + if (!DBM::is_result($r)) { throw new BadRequestException("album not available"); + } // function for setting the items to "deleted = 1" which ensures that comments, likes etc. are not shown anymore // to the user and the contacts of the users (drop_items() performs the federation of the deletion to other networks @@ -3751,16 +3988,16 @@ function api_fr_photoalbum_delete($type) if (!DBM::is_result($photo_item)) { throw new InternalServerErrorException("problem with deleting items occured"); } - drop_item($photo_item[0]['id'], false); + Item::delete($photo_item[0]['id']); } // now let's delete all photos from the album - $result = dba::delete('photo', array('uid' => api_user(), 'album' => $album)); + $result = dba::delete('photo', ['uid' => api_user(), 'album' => $album]); // return success of deletion or error message if ($result) { - $answer = array('result' => 'deleted', 'message' => 'album `' . $album . '` with all containing photos has been deleted.'); - return api_format_data("photoalbum_delete", $type, array('$result' => $answer)); + $answer = ['result' => 'deleted', 'message' => 'album `' . $album . '` with all containing photos has been deleted.']; + return api_format_data("photoalbum_delete", $type, ['$result' => $answer]); } else { throw new InternalServerErrorException("unknown error - deleting from database failed"); } @@ -3807,8 +4044,8 @@ function api_fr_photoalbum_update($type) // return success of updating or error message if ($result) { - $answer = array('result' => 'updated', 'message' => 'album `' . $album . '` with all containing photos has been renamed to `' . $album_new . '`.'); - return api_format_data("photoalbum_update", $type, array('$result' => $answer)); + $answer = ['result' => 'updated', 'message' => 'album `' . $album . '` with all containing photos has been renamed to `' . $album_new . '`.']; + return api_format_data("photoalbum_update", $type, ['$result' => $answer]); } else { throw new InternalServerErrorException("unknown error - updating in database failed"); } @@ -3832,15 +4069,15 @@ function api_fr_photos_list($type) WHERE `uid` = %d AND `album` != 'Contact Photos' GROUP BY `resource-id`", intval(local_user()) ); - $typetoext = array( + $typetoext = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif' - ); - $data = array('photo'=>array()); + ]; + $data = ['photo'=>[]]; if (DBM::is_result($r)) { foreach ($r as $rr) { - $photo = array(); + $photo = []; $photo['id'] = $rr['resource-id']; $photo['album'] = $rr['album']; $photo['filename'] = $rr['filename']; @@ -3851,7 +4088,7 @@ function api_fr_photos_list($type) $photo['desc'] = $rr['desc']; if ($type == "xml") { - $data['photo'][] = array("@attributes" => $photo, "1" => $thumb); + $data['photo'][] = ["@attributes" => $photo, "1" => $thumb]; } else { $photo['thumb'] = $thumb; $data['photo'][] = $photo; @@ -3995,12 +4232,12 @@ function api_fr_photo_create_update($type) // return success of updating or error message if ($result) { - $answer = array('result' => 'updated', 'message' => 'Image id `' . $photo_id . '` has been updated.'); - return api_format_data("photo_update", $type, array('$result' => $answer)); + $answer = ['result' => 'updated', 'message' => 'Image id `' . $photo_id . '` has been updated.']; + return api_format_data("photo_update", $type, ['$result' => $answer]); } else { if ($nothingtodo) { - $answer = array('result' => 'cancelled', 'message' => 'Nothing to update for image id `' . $photo_id . '`.'); - return api_format_data("photo_update", $type, array('$result' => $answer)); + $answer = ['result' => 'cancelled', 'message' => 'Nothing to update for image id `' . $photo_id . '`.']; + return api_format_data("photo_update", $type, ['$result' => $answer]); } throw new InternalServerErrorException("unknown error - update photo entry in database failed"); } @@ -4038,7 +4275,7 @@ function api_fr_photo_delete($type) throw new BadRequestException("photo not available"); } // now we can perform on the deletion of the photo - $result = dba::delete('photo', array('uid' => api_user(), 'resource-id' => $photo_id)); + $result = dba::delete('photo', ['uid' => api_user(), 'resource-id' => $photo_id]); // return success of deletion or error message if ($result) { @@ -4054,10 +4291,10 @@ function api_fr_photo_delete($type) } // function for setting the items to "deleted = 1" which ensures that comments, likes etc. are not shown anymore // to the user and the contacts of the users (drop_items() do all the necessary magic to avoid orphans in database and federate deletion) - drop_item($photo_item[0]['id'], false); + Item::delete($photo_item[0]['id']); - $answer = array('result' => 'deleted', 'message' => 'photo with id `' . $photo_id . '` has been deleted from server.'); - return api_format_data("photo_delete", $type, array('$result' => $answer)); + $answer = ['result' => 'deleted', 'message' => 'photo with id `' . $photo_id . '` has been deleted from server.']; + return api_format_data("photo_delete", $type, ['$result' => $answer]); } else { throw new InternalServerErrorException("unknown error on deleting photo from database table"); } @@ -4068,7 +4305,7 @@ function api_fr_photo_delete($type) * @brief returns the details of a specified photo id, if scale is given, returns the photo data in base 64 * * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string + * @return string|array */ function api_fr_photo_detail($type) { @@ -4090,10 +4327,14 @@ function api_fr_photo_detail($type) /** + * Updates the user’s profile image. + * * @brief updates the profile image for the user (either a specified profile or the default profile) * * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * * @return string + * @see https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_image */ function api_account_update_profile_image($type) { @@ -4101,7 +4342,7 @@ function api_account_update_profile_image($type) throw new ForbiddenException(); } // input params - $profileid = (x($_REQUEST, 'profile_id') ? $_REQUEST['profile_id'] : 0); + $profileid = defaults($_REQUEST, 'profile_id', 0); // error if image data is missing if (!x($_FILES, 'image')) { @@ -4147,13 +4388,13 @@ function api_account_update_profile_image($type) } // change specified profile or all profiles to the new resource-id if ($is_default_profile) { - $r = q( + q( "UPDATE `photo` SET `profile` = 0 WHERE `profile` = 1 AND `resource-id` != '%s' AND `uid` = %d", dbesc($data['photo']['id']), intval(local_user()) ); - $r = q( + q( "UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s' WHERE `self` AND `uid` = %d", dbesc(System::baseUrl() . '/photo/' . $data['photo']['id'] . '-4.' . $fileext), dbesc(System::baseUrl() . '/photo/' . $data['photo']['id'] . '-5.' . $fileext), @@ -4161,7 +4402,7 @@ function api_account_update_profile_image($type) intval(local_user()) ); } else { - $r = q( + q( "UPDATE `profile` SET `photo` = '%s', `thumb` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc(System::baseUrl() . '/photo/' . $data['photo']['id'] . '-4.' . $filetype), dbesc(System::baseUrl() . '/photo/' . $data['photo']['id'] . '-5.' . $filetype), @@ -4173,7 +4414,7 @@ function api_account_update_profile_image($type) // we'll set the updated profile-photo timestamp even if it isn't the default profile, // so that browsers will do a cache update unconditionally - $r = q( + q( "UPDATE `contact` SET `avatar-date` = '%s' WHERE `self` = 1 AND `uid` = %d", dbesc(datetime_convert()), intval(local_user()) @@ -4207,7 +4448,47 @@ api_register_func('api/friendica/photo/delete', 'api_fr_photo_delete', true, API api_register_func('api/friendica/photo', 'api_fr_photo_detail', true); api_register_func('api/account/update_profile_image', 'api_account_update_profile_image', true, API_METHOD_POST); +/** + * Update user profile + * + * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * + * @return array|string + */ +function api_account_update_profile($type) +{ + $local_user = api_user(); + $api_user = api_get_user(get_app()); + + if (!empty($_POST['name'])) { + dba::update('profile', ['name' => $_POST['name']], ['uid' => $local_user]); + dba::update('user', ['username' => $_POST['name']], ['uid' => $local_user]); + dba::update('contact', ['name' => $_POST['name']], ['uid' => $local_user, 'self' => 1]); + dba::update('contact', ['name' => $_POST['name']], ['id' => $api_user['id']]); + } + if (isset($_POST['description'])) { + dba::update('profile', ['about' => $_POST['description']], ['uid' => $local_user]); + dba::update('contact', ['about' => $_POST['description']], ['uid' => $local_user, 'self' => 1]); + dba::update('contact', ['about' => $_POST['description']], ['id' => $api_user['id']]); + } + + Worker::add(PRIORITY_LOW, 'ProfileUpdate', $local_user); + // Update global directory in background + if ($api_user['url'] && strlen(Config::get('system', 'directory'))) { + Worker::add(PRIORITY_LOW, "Directory", $api_user['url']); + } + + return api_account_verify_credentials($type); +} + +/// @TODO move to top of file or somewhere better +api_register_func('api/account/update_profile', 'api_account_update_profile', true, API_METHOD_POST); + +/** + * + * @param string $acl_string + */ function check_acl_input($acl_string) { if ($acl_string == null || $acl_string == " ") { @@ -4233,6 +4514,21 @@ function check_acl_input($acl_string) return $contact_not_found; } +/** + * + * @param string $mediatype + * @param array $media + * @param string $type + * @param string $album + * @param string $allow_cid + * @param string $deny_cid + * @param string $allow_gid + * @param string $deny_gid + * @param string $desc + * @param integer $profile + * @param boolean $visibility + * @param string $photo_id + */ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $desc, $profile = 0, $visibility = false, $photo_id = null) { $visitor = 0; @@ -4273,7 +4569,8 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ } logger( "File upload src: " . $src . " - filename: " . $filename . - " - size: " . $filesize . " - type: " . $filetype, LOGGER_DEBUG + " - size: " . $filesize . " - type: " . $filetype, + LOGGER_DEBUG ); // check if there was a php upload error @@ -4282,7 +4579,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ } // check against max upload size within Friendica instance $maximagesize = Config::get('system', 'maximagesize'); - if (($maximagesize) && ($filesize > $maximagesize)) { + if ($maximagesize && ($filesize > $maximagesize)) { $formattedBytes = formatBytes($maximagesize); throw new InternalServerErrorException("image size exceeds Friendica config setting (uploaded size: $formattedBytes)"); } @@ -4380,13 +4677,23 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ } } +/** + * + * @param string $hash + * @param string $allow_cid + * @param string $deny_cid + * @param string $allow_gid + * @param string $deny_gid + * @param string $filetype + * @param boolean $visibility + */ function post_photo_item($hash, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $filetype, $visibility = false) { // get data about the api authenticated user $uri = item_new_uri(get_app()->get_hostname(), intval(api_user())); $owner_record = q("SELECT * FROM `contact` WHERE `uid`= %d AND `self` LIMIT 1", intval(api_user())); - $arr = array(); + $arr = []; $arr['guid'] = get_guid(32); $arr['uid'] = intval(api_user()); $arr['uri'] = $uri; @@ -4410,11 +4717,11 @@ function post_photo_item($hash, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $f $arr['visible'] = $visibility; $arr['origin'] = 1; - $typetoext = array( + $typetoext = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif' - ); + ]; // adds link to the thumbnail scale photo $arr['body'] = '[url=' . System::baseUrl() . '/photos/' . $owner_record[0]['nick'] . '/image/' . $hash . ']' @@ -4425,6 +4732,14 @@ function post_photo_item($hash, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $f item_store($arr); } +/** + * + * @param string $type + * @param int $scale + * @param string $photo_id + * + * @return array + */ function prepare_photo_data($type, $scale, $photo_id) { $scale_sql = ($scale === false ? "" : sprintf("AND scale=%d", intval($scale))); @@ -4443,15 +4758,15 @@ function prepare_photo_data($type, $scale, $photo_id) $scale_sql ); - $typetoext = array( + $typetoext = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif' - ); + ]; // prepare output data for photo if (DBM::is_result($r)) { - $data = array('photo' => $r[0]); + $data = ['photo' => $r[0]]; $data['photo']['id'] = $data['photo']['resource-id']; if ($scale !== false) { $data['photo']['data'] = base64_encode($data['photo']['data']); @@ -4459,14 +4774,14 @@ function prepare_photo_data($type, $scale, $photo_id) unset($data['photo']['datasize']); //needed only with scale param } if ($type == "xml") { - $data['photo']['links'] = array(); + $data['photo']['links'] = []; for ($k = intval($data['photo']['minscale']); $k <= intval($data['photo']['maxscale']); $k++) { - $data['photo']['links'][$k . ":link"]["@attributes"] = array("type" => $data['photo']['type'], + $data['photo']['links'][$k . ":link"]["@attributes"] = ["type" => $data['photo']['type'], "scale" => $k, - "href" => System::baseUrl() . "/photo/" . $data['photo']['resource-id'] . "-" . $k . "." . $typetoext[$data['photo']['type']]); + "href" => System::baseUrl() . "/photo/" . $data['photo']['resource-id'] . "-" . $k . "." . $typetoext[$data['photo']['type']]]; } } else { - $data['photo']['link'] = array(); + $data['photo']['link'] = []; // when we have profile images we could have only scales from 4 to 6, but index of array always needs to start with 0 $i = 0; for ($k = intval($data['photo']['minscale']); $k <= intval($data['photo']['maxscale']); $k++) { @@ -4508,7 +4823,7 @@ function prepare_photo_data($type, $scale, $photo_id) // prepare output of comments $commentData = api_format_items($r, api_get_user(get_app()), false, $type); - $comments = array(); + $comments = []; if ($type == "xml") { $k = 0; foreach ($commentData as $comment) { @@ -4545,8 +4860,8 @@ function prepare_photo_data($type, $scale, $photo_id) */ function api_friendica_remoteauth() { - $url = ((x($_GET, 'url')) ? $_GET['url'] : ''); - $c_url = ((x($_GET, 'c_url')) ? $_GET['c_url'] : ''); + $url = (x($_GET, 'url') ? $_GET['url'] : ''); + $c_url = (x($_GET, 'c_url') ? $_GET['c_url'] : ''); if ($url === '' || $c_url === '') { throw new BadRequestException("Wrong parameters."); @@ -4556,26 +4871,22 @@ function api_friendica_remoteauth() // traditional DFRN - $r = q( - "SELECT * FROM `contact` WHERE `id` = %d AND `nurl` = '%s' LIMIT 1", - dbesc($c_url), - intval(api_user()) - ); + $contact = dba::selectFirst('contact', [], ['uid' => api_user(), 'nurl' => $c_url]); - if ((! DBM::is_result($r)) || ($r[0]['network'] !== NETWORK_DFRN)) { + if (!DBM::is_result($contact) || ($contact['network'] !== NETWORK_DFRN)) { throw new BadRequestException("Unknown contact"); } - $cid = $r[0]['id']; + $cid = $contact['id']; - $dfrn_id = $orig_id = (($r[0]['issued-id']) ? $r[0]['issued-id'] : $r[0]['dfrn-id']); + $dfrn_id = defaults($contact, 'issued-id', $contact['dfrn-id']); - if ($r[0]['duplex'] && $r[0]['issued-id']) { - $orig_id = $r[0]['issued-id']; + if ($contact['duplex'] && $contact['issued-id']) { + $orig_id = $contact['issued-id']; $dfrn_id = '1:' . $orig_id; } - if ($r[0]['duplex'] && $r[0]['dfrn-id']) { - $orig_id = $r[0]['dfrn-id']; + if ($contact['duplex'] && $contact['dfrn-id']) { + $orig_id = $contact['dfrn-id']; $dfrn_id = '0:' . $orig_id; } @@ -4591,10 +4902,10 @@ function api_friendica_remoteauth() intval(time() + 45) ); - logger($r[0]['name'] . ' ' . $sec, LOGGER_DEBUG); - $dest = (($url) ? '&destination_url=' . $url : ''); + logger($contact['name'] . ' ' . $sec, LOGGER_DEBUG); + $dest = ($url ? '&destination_url=' . $url : ''); goaway( - $r[0]['poll'] . '?dfrn_id=' . $dfrn_id + $contact['poll'] . '?dfrn_id=' . $dfrn_id . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=profile&sec=' . $sec . $dest . $quiet ); @@ -4605,7 +4916,7 @@ api_register_func('api/friendica/remoteauth', 'api_friendica_remoteauth', true); * @brief Return the item shared, if the item contains only the [share] tag * * @param array $item Sharer item - * @return array Shared item or false if not a reshare + * @return array|false Shared item or false if not a reshare */ function api_share_as_retweet(&$item) { @@ -4676,8 +4987,9 @@ function api_share_as_retweet(&$item) $posted = ""; preg_match("/posted='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") + if ($matches[1] != "") { $posted = $matches[1]; + } preg_match('/posted="(.*?)"/ism', $attributes, $matches); if ($matches[1] != "") { @@ -4699,16 +5011,18 @@ function api_share_as_retweet(&$item) $reshared_item["edited"] = $posted; return $reshared_item; - } +/** + * + * @param string $profile + * + * @return string|false + * @todo remove trailing junk from profile url + * @todo pump.io check has to check the website + */ function api_get_nick($profile) { - /* To-Do: - - remove trailing junk from profile url - - pump.io check has to check the website - */ - $nick = ""; $r = q( @@ -4783,9 +5097,15 @@ function api_get_nick($profile) return false; } +/** + * + * @param array $item + * + * @return array + */ function api_in_reply_to($item) { - $in_reply_to = array(); + $in_reply_to = []; $in_reply_to['status_id'] = null; $in_reply_to['user_id'] = null; @@ -4794,9 +5114,11 @@ function api_in_reply_to($item) $in_reply_to['screen_name'] = null; if (($item['thr-parent'] != $item['uri']) && (intval($item['parent']) != intval($item['id']))) { - $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1", + $r = q( + "SELECT `id` FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1", intval($item['uid']), - dbesc($item['thr-parent'])); + dbesc($item['thr-parent']) + ); if (DBM::is_result($r)) { $in_reply_to['status_id'] = intval($r[0]['id']); @@ -4806,7 +5128,8 @@ function api_in_reply_to($item) $in_reply_to['status_id_str'] = (string) intval($in_reply_to['status_id']); - $r = q("SELECT `contact`.`nick`, `contact`.`name`, `contact`.`id`, `contact`.`url` FROM item + $r = q( + "SELECT `contact`.`nick`, `contact`.`name`, `contact`.`id`, `contact`.`url` FROM item STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`author-id` WHERE `item`.`id` = %d LIMIT 1", intval($in_reply_to['status_id']) @@ -4838,6 +5161,12 @@ function api_in_reply_to($item) return $in_reply_to; } +/** + * + * @param string $Text + * + * @return string + */ function api_clean_plain_items($Text) { $include_entities = strtolower(x($_REQUEST, 'include_entities') ? $_REQUEST['include_entities'] : "false"); @@ -4868,76 +5197,107 @@ function api_clean_attachments($body) { $data = get_attachment_data($body); - if (!$data) + if (!$data) { return $body; - + } $body = ""; - if (isset($data["text"])) + if (isset($data["text"])) { $body = $data["text"]; - - if (($body == "") && (isset($data["title"]))) + } + if (($body == "") && isset($data["title"])) { $body = $data["title"]; - - if (isset($data["url"])) + } + if (isset($data["url"])) { $body .= "\n".$data["url"]; - + } $body .= $data["after"]; return $body; } +/** + * + * @param array $contacts + * + * @return array + */ function api_best_nickname(&$contacts) { - $best_contact = array(); + $best_contact = []; - if (count($contact) == 0) + if (count($contact) == 0) { return; + } - foreach ($contacts as $contact) + foreach ($contacts as $contact) { if ($contact["network"] == "") { $contact["network"] = "dfrn"; - $best_contact = array($contact); + $best_contact = [$contact]; } + } - if (sizeof($best_contact) == 0) - foreach ($contacts as $contact) - if ($contact["network"] == "dfrn") - $best_contact = array($contact); + if (sizeof($best_contact) == 0) { + foreach ($contacts as $contact) { + if ($contact["network"] == "dfrn") { + $best_contact = [$contact]; + } + } + } - if (sizeof($best_contact) == 0) - foreach ($contacts as $contact) - if ($contact["network"] == "dspr") - $best_contact = array($contact); + if (sizeof($best_contact) == 0) { + foreach ($contacts as $contact) { + if ($contact["network"] == "dspr") { + $best_contact = [$contact]; + } + } + } - if (sizeof($best_contact) == 0) - foreach ($contacts as $contact) - if ($contact["network"] == "stat") - $best_contact = array($contact); + if (sizeof($best_contact) == 0) { + foreach ($contacts as $contact) { + if ($contact["network"] == "stat") { + $best_contact = [$contact]; + } + } + } - if (sizeof($best_contact) == 0) - foreach ($contacts as $contact) - if ($contact["network"] == "pump") - $best_contact = array($contact); + if (sizeof($best_contact) == 0) { + foreach ($contacts as $contact) { + if ($contact["network"] == "pump") { + $best_contact = [$contact]; + } + } + } - if (sizeof($best_contact) == 0) - foreach ($contacts as $contact) - if ($contact["network"] == "twit") - $best_contact = array($contact); + if (sizeof($best_contact) == 0) { + foreach ($contacts as $contact) { + if ($contact["network"] == "twit") { + $best_contact = [$contact]; + } + } + } if (sizeof($best_contact) == 1) { $contacts = $best_contact; } else { - $contacts = array($contacts[0]); + $contacts = [$contacts[0]]; } } -// return all or a specified group of the user with the containing contacts +/** + * Return all or a specified group of the user with the containing contacts. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_friendica_group_show($type) { $a = get_app(); - if (api_user() === false) throw new ForbiddenException(); + if (api_user() === false) { + throw new ForbiddenException(); + } // params $user_info = api_get_user($a); @@ -4952,8 +5312,9 @@ function api_friendica_group_show($type) intval($gid) ); // error message if specified gid is not in database - if (!DBM::is_result($r)) + if (!DBM::is_result($r)) { throw new BadRequestException("gid not available"); + } } else { $r = q( "SELECT * FROM `group` WHERE `deleted` = 0 AND `uid` = %d", @@ -4964,7 +5325,7 @@ function api_friendica_group_show($type) // loop through all groups and retrieve all members for adding data in the user array foreach ($r as $rr) { $members = Contact::getByGroupId($rr['id']); - $users = array(); + $users = []; if ($type == "xml") { $user_element = "users"; @@ -4980,14 +5341,20 @@ function api_friendica_group_show($type) $users[] = $user; } } - $grps[] = array('name' => $rr['name'], 'gid' => $rr['id'], $user_element => $users); + $grps[] = ['name' => $rr['name'], 'gid' => $rr['id'], $user_element => $users]; } - return api_format_data("groups", $type, array('group' => $grps)); + return api_format_data("groups", $type, ['group' => $grps]); } api_register_func('api/friendica/group_show', 'api_friendica_group_show', true); -// delete the specified group of the user +/** + * Delete the specified group of the user. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_friendica_group_delete($type) { $a = get_app(); @@ -5034,8 +5401,8 @@ function api_friendica_group_delete($type) $ret = Group::removeByName($uid, $name); if ($ret) { // return success - $success = array('success' => $ret, 'gid' => $gid, 'name' => $name, 'status' => 'deleted', 'wrong users' => array()); - return api_format_data("group_delete", $type, array('result' => $success)); + $success = ['success' => $ret, 'gid' => $gid, 'name' => $name, 'status' => 'deleted', 'wrong users' => []]; + return api_format_data("group_delete", $type, ['result' => $success]); } else { throw new BadRequestException('other API error'); } @@ -5043,12 +5410,20 @@ function api_friendica_group_delete($type) api_register_func('api/friendica/group_delete', 'api_friendica_group_delete', true, API_METHOD_DELETE); -// create the specified group with the posted array of contacts +/** + * Create the specified group with the posted array of contacts. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_friendica_group_create($type) { $a = get_app(); - if (api_user() === false) throw new ForbiddenException(); + if (api_user() === false) { + throw new ForbiddenException(); + } // params $user_info = api_get_user($a); @@ -5058,8 +5433,9 @@ function api_friendica_group_create($type) $users = $json['user']; // error if no name specified - if ($name == "") + if ($name == "") { throw new BadRequestException('group name not specified'); + } // get data of the specified group name $rname = q( @@ -5068,8 +5444,9 @@ function api_friendica_group_create($type) dbesc($name) ); // error message if specified group name already exists - if (DBM::is_result($rname)) + if (DBM::is_result($rname)) { throw new BadRequestException('group name already exists'); + } // check if specified group name is a deleted group $rname = q( @@ -5078,8 +5455,9 @@ function api_friendica_group_create($type) dbesc($name) ); // error message if specified group name already exists - if (DBM::is_result($rname)) + if (DBM::is_result($rname)) { $reactivate_group = true; + } // create group $ret = Group::create($uid, $name); @@ -5091,7 +5469,7 @@ function api_friendica_group_create($type) // add members $erroraddinguser = false; - $errorusers = array(); + $errorusers = []; foreach ($users as $user) { $cid = $user['cid']; // check if user really exists as contact @@ -5100,9 +5478,9 @@ function api_friendica_group_create($type) intval($cid), intval($uid) ); - if (count($contact)) - $result = Group::addMember($gid, $cid); - else { + if (count($contact)) { + Group::addMember($gid, $cid); + } else { $erroraddinguser = true; $errorusers[] = $cid; } @@ -5110,18 +5488,26 @@ function api_friendica_group_create($type) // return success message incl. missing users in array $status = ($erroraddinguser ? "missing user" : ($reactivate_group ? "reactivated" : "ok")); - $success = array('success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers); - return api_format_data("group_create", $type, array('result' => $success)); + $success = ['success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers]; + return api_format_data("group_create", $type, ['result' => $success]); } api_register_func('api/friendica/group_create', 'api_friendica_group_create', true, API_METHOD_POST); -// update the specified group with the posted array of contacts +/** + * Update the specified group with the posted array of contacts. + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_friendica_group_update($type) { $a = get_app(); - if (api_user() === false) throw new ForbiddenException(); + if (api_user() === false) { + throw new ForbiddenException(); + } // params $user_info = api_get_user($a); @@ -5132,12 +5518,14 @@ function api_friendica_group_update($type) $users = $json['user']; // error if no name specified - if ($name == "") + if ($name == "") { throw new BadRequestException('group name not specified'); + } // error if no gid specified - if ($gid == "") + if ($gid == "") { throw new BadRequestException('gid not specified'); + } // remove members $members = Contact::getByGroupId($gid); @@ -5147,13 +5535,13 @@ function api_friendica_group_update($type) $found = ($user['cid'] == $cid ? true : false); } if (!$found) { - $ret = Group::removeMemberByName($uid, $name, $cid); + Group::removeMemberByName($uid, $name, $cid); } } // add members $erroraddinguser = false; - $errorusers = array(); + $errorusers = []; foreach ($users as $user) { $cid = $user['cid']; // check if user really exists as contact @@ -5164,7 +5552,7 @@ function api_friendica_group_update($type) ); if (count($contact)) { - $result = Group::addMember($gid, $cid); + Group::addMember($gid, $cid); } else { $erroraddinguser = true; $errorusers[] = $cid; @@ -5173,17 +5561,25 @@ function api_friendica_group_update($type) // return success message incl. missing users in array $status = ($erroraddinguser ? "missing user" : "ok"); - $success = array('success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers); - return api_format_data("group_update", $type, array('result' => $success)); + $success = ['success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers]; + return api_format_data("group_update", $type, ['result' => $success]); } api_register_func('api/friendica/group_update', 'api_friendica_group_update', true, API_METHOD_POST); +/** + * + * @param string $type Return type (atom, rss, xml, json) + * + * @return array|string + */ function api_friendica_activity($type) { $a = get_app(); - if (api_user() === false) throw new ForbiddenException(); + if (api_user() === false) { + throw new ForbiddenException(); + } $verb = strtolower($a->argv[3]); $verb = preg_replace("|\..*$|", "", $verb); @@ -5197,13 +5593,13 @@ function api_friendica_activity($type) } else { $ok = "ok"; } - return api_format_data('ok', $type, array('ok' => $ok)); + return api_format_data('ok', $type, ['ok' => $ok]); } else { throw new BadRequestException('Error adding activity'); } } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/friendica/activity/like', 'api_friendica_activity', true, API_METHOD_POST); api_register_func('api/friendica/activity/dislike', 'api_friendica_activity', true, API_METHOD_POST); api_register_func('api/friendica/activity/attendyes', 'api_friendica_activity', true, API_METHOD_POST); @@ -5225,28 +5621,33 @@ function api_friendica_notification($type) { $a = get_app(); - if (api_user() === false) throw new ForbiddenException(); - if ($a->argc!==3) throw new BadRequestException("Invalid argument count"); + if (api_user() === false) { + throw new ForbiddenException(); + } + if ($a->argc!==3) { + throw new BadRequestException("Invalid argument count"); + } $nm = new NotificationsManager(); - $notes = $nm->getAll(array(), "+seen -date", 50); + $notes = $nm->getAll([], "+seen -date", 50); if ($type == "xml") { - $xmlnotes = array(); - foreach ($notes as $note) - $xmlnotes[] = array("@attributes" => $note); + $xmlnotes = []; + foreach ($notes as $note) { + $xmlnotes[] = ["@attributes" => $note]; + } $notes = $xmlnotes; } - return api_format_data("notes", $type, array('note' => $notes)); + return api_format_data("notes", $type, ['note' => $notes]); } /** - * @brief Set notification as seen and returns associated item (if possible) - * * POST request with 'id' param as notification id * + * @brief Set notification as seen and returns associated item (if possible) + * * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' * @return string */ @@ -5254,14 +5655,20 @@ function api_friendica_notification_seen($type) { $a = get_app(); - if (api_user() === false) throw new ForbiddenException(); - if ($a->argc!==4) throw new BadRequestException("Invalid argument count"); + if (api_user() === false) { + throw new ForbiddenException(); + } + if ($a->argc!==4) { + throw new BadRequestException("Invalid argument count"); + } $id = (x($_REQUEST, 'id') ? intval($_REQUEST['id']) : 0); $nm = new NotificationsManager(); $note = $nm->getByID($id); - if (is_null($note)) throw new BadRequestException("Invalid argument"); + if (is_null($note)) { + throw new BadRequestException("Invalid argument"); + } $nm->setSeen($note); if ($note['otype']=='item') { @@ -5275,15 +5682,15 @@ function api_friendica_notification_seen($type) // we found the item, return it to the user $user_info = api_get_user($a); $ret = api_format_items($r, $user_info, false, $type); - $data = array('status' => $ret); + $data = ['status' => $ret]; return api_format_data("status", $type, $data); } // the item can't be found, but we set the note as seen, so we count this as a success } - return api_format_data('result', $type, array('result' => "success")); + return api_format_data('result', $type, ['result' => "success"]); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/friendica/notification/seen', 'api_friendica_notification_seen', true, API_METHOD_POST); api_register_func('api/friendica/notification', 'api_friendica_notification', true, API_METHOD_GET); @@ -5307,8 +5714,8 @@ function api_friendica_direct_messages_setseen($type) // return error if id is zero if ($id == "") { - $answer = array('result' => 'error', 'message' => 'message id not specified'); - return api_format_data("direct_messages_setseen", $type, array('$result' => $answer)); + $answer = ['result' => 'error', 'message' => 'message id not specified']; + return api_format_data("direct_messages_setseen", $type, ['$result' => $answer]); } // get data of the specified message id @@ -5320,8 +5727,8 @@ function api_friendica_direct_messages_setseen($type) // error message if specified id is not in database if (!DBM::is_result($r)) { - $answer = array('result' => 'error', 'message' => 'message id not in database'); - return api_format_data("direct_messages_setseen", $type, array('$result' => $answer)); + $answer = ['result' => 'error', 'message' => 'message id not in database']; + return api_format_data("direct_messages_setseen", $type, ['$result' => $answer]); } // update seen indicator @@ -5333,22 +5740,22 @@ function api_friendica_direct_messages_setseen($type) if ($result) { // return success - $answer = array('result' => 'ok', 'message' => 'message set to seen'); - return api_format_data("direct_message_setseen", $type, array('$result' => $answer)); + $answer = ['result' => 'ok', 'message' => 'message set to seen']; + return api_format_data("direct_message_setseen", $type, ['$result' => $answer]); } else { - $answer = array('result' => 'error', 'message' => 'unknown error'); - return api_format_data("direct_messages_setseen", $type, array('$result' => $answer)); + $answer = ['result' => 'error', 'message' => 'unknown error']; + return api_format_data("direct_messages_setseen", $type, ['$result' => $answer]); } } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/friendica/direct_messages_setseen', 'api_friendica_direct_messages_setseen', true); /** * @brief search for direct_messages containing a searchstring through api * * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string (success: success=true if found and search_result contains found messages + * @return string (success: success=true if found and search_result contains found messages, * success=false if nothing was found, search_result='nothing found', * error: result=error with error message) */ @@ -5367,8 +5774,8 @@ function api_friendica_direct_messages_search($type) // error if no searchstring specified if ($searchstring == "") { - $answer = array('result' => 'error', 'message' => 'searchstring not specified'); - return api_format_data("direct_messages_search", $type, array('$result' => $answer)); + $answer = ['result' => 'error', 'message' => 'searchstring not specified']; + return api_format_data("direct_messages_search", $type, ['$result' => $answer]); } // get data for the specified searchstring @@ -5382,11 +5789,11 @@ function api_friendica_direct_messages_search($type) // message if nothing was found if (!DBM::is_result($r)) { - $success = array('success' => false, 'search_results' => 'problem with query'); + $success = ['success' => false, 'search_results' => 'problem with query']; } elseif (count($r) == 0) { - $success = array('success' => false, 'search_results' => 'nothing found'); + $success = ['success' => false, 'search_results' => 'nothing found']; } else { - $ret = array(); + $ret = []; foreach ($r as $item) { if ($box == "inbox" || $item['from-url'] != $profile_url) { $recipient = $user_info; @@ -5398,13 +5805,13 @@ function api_friendica_direct_messages_search($type) $ret[] = api_format_messages($item, $recipient, $sender); } - $success = array('success' => true, 'search_results' => $ret); + $success = ['success' => true, 'search_results' => $ret]; } - return api_format_data("direct_message_search", $type, array('$result' => $success)); + return api_format_data("direct_message_search", $type, ['$result' => $success]); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/friendica/direct_messages_search', 'api_friendica_direct_messages_search', true); /** @@ -5449,10 +5856,10 @@ function api_friendica_profile_show($type) // loop through all returned profiles and retrieve data and users $k = 0; foreach ($r as $rr) { - $profile = api_format_items_profiles($rr, $type); + $profile = api_format_items_profiles($rr); // select all users from contact table, loop and prepare standard return for user data - $users = array(); + $users = []; $r = q( "SELECT `id`, `nurl` FROM `contact` WHERE `uid`= %d AND `profile-id` = %d", intval(api_user()), @@ -5476,11 +5883,11 @@ function api_friendica_profile_show($type) // return settings, authenticated user and profiles data $self = q("SELECT `nurl` FROM `contact` WHERE `uid`= %d AND `self` LIMIT 1", intval(api_user())); - $result = array('multi_profiles' => $multi_profiles ? true : false, + $result = ['multi_profiles' => $multi_profiles ? true : false, 'global_dir' => $directory, 'friendica_owner' => api_get_user($a, $self[0]['nurl']), - 'profiles' => $profiles); - return api_format_data("friendica_profiles", $type, array('$result' => $result)); + 'profiles' => $profiles]; + return api_format_data("friendica_profiles", $type, ['$result' => $result]); } api_register_func('api/friendica/profile/show', 'api_friendica_profile_show', true, API_METHOD_GET); @@ -5495,38 +5902,38 @@ api_register_func('api/friendica/profile/show', 'api_friendica_profile_show', tr */ function api_saved_searches_list($type) { - $terms = dba::select('search', array('id', 'term'), array('uid' => local_user())); + $terms = dba::select('search', ['id', 'term'], ['uid' => local_user()]); - $result = array(); + $result = []; while ($term = $terms->fetch()) { - $result[] = array( + $result[] = [ 'name' => $term['term'], 'query' => $term['term'], 'id_str' => $term['id'], 'id' => intval($term['id']) - ); + ]; } dba::close($terms); - return api_format_data("terms", $type, array('terms' => $result)); + return api_format_data("terms", $type, ['terms' => $result]); } -/// @TODO move to top of file or somwhere better +/// @TODO move to top of file or somewhere better api_register_func('api/saved_searches/list', 'api_saved_searches_list', true); /* @TODO Maybe open to implement? To.Do: - [pagename] => api/1.1/statuses/lookup.json - [id] => 605138389168451584 - [include_cards] => true - [cards_platform] => Android-12 - [include_entities] => true - [include_my_retweet] => 1 - [include_rts] => 1 - [include_reply_count] => true - [include_descendent_reply_count] => true + [pagename] => api/1.1/statuses/lookup.json + [id] => 605138389168451584 + [include_cards] => true + [cards_platform] => Android-12 + [include_entities] => true + [include_my_retweet] => 1 + [include_rts] => 1 + [include_reply_count] => true + [include_descendent_reply_count] => true (?)