- if ($result === null) {
- Logger::notice(API_LOG_PREFIX . 'Not supported for {network}', ['module' => 'api', 'action' => 'friendships_destroy', 'network' => $contact['network']]);
- throw new HTTPException\ExpectationFailedException('Unfollowing is currently not supported by this contact\'s network.');
- }
-
- if ($result === false) {
- throw new HTTPException\ServiceUnavailableException('Unable to unfollow this contact, please retry in a few minutes or contact your administrator.');
- }
- } catch (Exception $e) {
- Logger::error(API_LOG_PREFIX . $e->getMessage(), ['owner' => $owner, 'contact' => $contact]);
- throw new HTTPException\InternalServerErrorException('Unable to unfollow this contact, please contact your administrator');
- }
-
- // "uid" and "self" are only needed for some internal stuff, so remove it from here
- unset($contact['uid']);
- unset($contact['self']);
-
- // Set screen_name since Twidere requests it
- $contact['screen_name'] = $contact['nick'];
-
- return BaseApi::formatData('friendships-destroy', $type, ['user' => $contact]);
-}
-api_register_func('api/friendships/destroy', 'api_friendships_destroy', true, API_METHOD_POST);
-
-/**
- *
- * @param string $type Return type (atom, rss, xml, json)
- * @param string $box
- * @param string $verbose
- *
- * @return array|string
- * @throws BadRequestException
- * @throws ForbiddenException
- * @throws ImagickException
- * @throws InternalServerErrorException
- * @throws UnauthorizedException
- */
-function api_direct_messages_box($type, $box, $verbose)
-{
- $a = DI::app();
- if (api_user() === false) {
- throw new ForbiddenException();
- }
- // params
- $count = $_GET['count'] ?? 20;
- $page = $_REQUEST['page'] ?? 1;
-
- $since_id = $_REQUEST['since_id'] ?? 0;
- $max_id = $_REQUEST['max_id'] ?? 0;
-
- $user_id = $_REQUEST['user_id'] ?? '';
- $screen_name = $_REQUEST['screen_name'] ?? '';
-
- // caller user info
- unset($_REQUEST["user_id"]);
- unset($_GET["user_id"]);
-
- unset($_REQUEST["screen_name"]);
- unset($_GET["screen_name"]);
-
- $user_info = api_get_user();
- if ($user_info === false) {
- throw new ForbiddenException();
- }
- $profile_url = $user_info["url"];
-
- // pagination
- $start = max(0, ($page - 1) * $count);
-
- $sql_extra = "";
-
- // filters
- if ($box=="sentbox") {
- $sql_extra = "`mail`.`from-url`='" . DBA::escape($profile_url) . "'";
- } elseif ($box == "conversation") {
- $sql_extra = "`mail`.`parent-uri`='" . DBA::escape($_GET['uri'] ?? '') . "'";
- } elseif ($box == "all") {
- $sql_extra = "true";
- } elseif ($box == "inbox") {
- $sql_extra = "`mail`.`from-url`!='" . DBA::escape($profile_url) . "'";
- }
-
- if ($max_id > 0) {
- $sql_extra .= ' AND `mail`.`id` <= ' . intval($max_id);
- }
-
- if ($user_id != "") {
- $sql_extra .= ' AND `mail`.`contact-id` = ' . intval($user_id);
- } elseif ($screen_name !="") {
- $sql_extra .= " AND `contact`.`nick` = '" . DBA::escape($screen_name). "'";
- }
-
- $r = DBA::toArray(DBA::p(
- "SELECT `mail`.*, `contact`.`nurl` AS `contact-url` FROM `mail`,`contact` WHERE `mail`.`contact-id` = `contact`.`id` AND `mail`.`uid` = ? AND $sql_extra AND `mail`.`id` > ? ORDER BY `mail`.`id` DESC LIMIT ?,?",
- api_user(),
- $since_id,
- $start,
- $count
- ));
- if ($verbose == "true" && !DBA::isResult($r)) {
- $answer = ['result' => 'error', 'message' => 'no mails available'];
- return BaseApi::formatData("direct_messages_all", $type, ['$result' => $answer]);
- }
-
- $ret = [];
- foreach ($r as $item) {
- if ($box == "inbox" || $item['from-url'] != $profile_url) {
- $recipient = $user_info;
- $sender = api_get_user(Strings::normaliseLink($item['contact-url']));
- } elseif ($box == "sentbox" || $item['from-url'] == $profile_url) {
- $recipient = api_get_user(Strings::normaliseLink($item['contact-url']));
- $sender = $user_info;
- }
-
- if (isset($recipient) && isset($sender)) {
- $ret[] = api_format_messages($item, $recipient, $sender);
- }
- }
-
-
- $data = ['direct_message' => $ret];
- switch ($type) {
- case "atom":
- break;
- case "rss":
- $data = api_rss_extra($a, $data, $user_info);
- break;
- }
-
- return BaseApi::formatData("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
- * @throws BadRequestException
- * @throws ForbiddenException
- * @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-sent-message
- */
-function api_direct_messages_sentbox($type)
-{
- $verbose = !empty($_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
- * @throws BadRequestException
- * @throws ForbiddenException
- * @see https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-messages
- */
-function api_direct_messages_inbox($type)
-{
- $verbose = !empty($_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
- * @throws BadRequestException
- * @throws ForbiddenException
- */
-function api_direct_messages_all($type)
-{
- $verbose = !empty($_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
- * @throws BadRequestException
- * @throws ForbiddenException
- */
-function api_direct_messages_conversation($type)
-{
- $verbose = !empty($_GET['friendica_verbose']) ? strtolower($_GET['friendica_verbose']) : "false";
- return api_direct_messages_box($type, "conversation", $verbose);
-}
-
-/// @TODO move to top of file or somewhere better
-api_register_func('api/direct_messages/conversation', 'api_direct_messages_conversation', true);
-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);
-
-/**
- * delete a complete photoalbum with all containing photos from database through api
- *
- * @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
- * @return string|array
- * @throws BadRequestException
- * @throws ForbiddenException
- * @throws InternalServerErrorException
- */
-function api_fr_photoalbum_delete($type)
-{
- if (api_user() === false) {
- throw new ForbiddenException();
- }
- // input params
- $album = $_REQUEST['album'] ?? '';
-
- // we do not allow calls without album string
- if ($album == "") {
- throw new BadRequestException("no albumname specified");
- }
- // check if album is existing
-
- $photos = DBA::selectToArray('photo', ['resource-id'], ['uid' => api_user(), 'album' => $album], ['group_by' => ['resource-id']]);
- if (!DBA::isResult($photos)) {
- throw new BadRequestException("album not available");
- }
-
- $resourceIds = array_column($photos, 'resource-id');
-
- // 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
- $condition = ['uid' => api_user(), 'resource-id' => $resourceIds, 'type' => 'photo'];
- Item::deleteForUser($condition, api_user());
-
- // now let's delete all photos from the album
- $result = Photo::delete(['uid' => api_user(), 'album' => $album]);
-
- // return success of deletion or error message
- if ($result) {
- $answer = ['result' => 'deleted', 'message' => 'album `' . $album . '` with all containing photos has been deleted.'];
- return BaseApi::formatData("photoalbum_delete", $type, ['$result' => $answer]);
- } else {
- throw new InternalServerErrorException("unknown error - deleting from database failed");
- }
-}
-
-/**
- * update the name of the album for all photos of an album
- *
- * @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
- * @return string|array
- * @throws BadRequestException
- * @throws ForbiddenException
- * @throws InternalServerErrorException
- */
-function api_fr_photoalbum_update($type)
-{
- if (api_user() === false) {
- throw new ForbiddenException();
- }
- // input params
- $album = $_REQUEST['album'] ?? '';
- $album_new = $_REQUEST['album_new'] ?? '';
-
- // we do not allow calls without album string
- if ($album == "") {
- throw new BadRequestException("no albumname specified");
- }
- if ($album_new == "") {
- throw new BadRequestException("no new albumname specified");
- }
- // check if album is existing
- if (!Photo::exists(['uid' => api_user(), 'album' => $album])) {
- throw new BadRequestException("album not available");
- }
- // now let's update all photos to the albumname
- $result = Photo::update(['album' => $album_new], ['uid' => api_user(), 'album' => $album]);
-
- // return success of updating or error message
- if ($result) {
- $answer = ['result' => 'updated', 'message' => 'album `' . $album . '` with all containing photos has been renamed to `' . $album_new . '`.'];
- return BaseApi::formatData("photoalbum_update", $type, ['$result' => $answer]);
- } else {
- throw new InternalServerErrorException("unknown error - updating in database failed");
- }
-}
-
-
-/**
- * list all photos of the authenticated user
- *
- * @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
- * @return string|array
- * @throws ForbiddenException
- * @throws InternalServerErrorException
- */
-function api_fr_photos_list($type)
-{
- if (api_user() === false) {
- throw new ForbiddenException();
- }
- $r = DBA::toArray(DBA::p(
- "SELECT `resource-id`, MAX(scale) AS `scale`, `album`, `filename`, `type`, MAX(`created`) AS `created`,
- MAX(`edited`) AS `edited`, MAX(`desc`) AS `desc` FROM `photo`
- WHERE `uid` = ? AND NOT `photo-type` IN (?, ?) GROUP BY `resource-id`, `album`, `filename`, `type`",
- local_user(), Photo::CONTACT_AVATAR, Photo::CONTACT_BANNER
- ));
- $typetoext = [
- 'image/jpeg' => 'jpg',
- 'image/png' => 'png',
- 'image/gif' => 'gif'
- ];
- $data = ['photo'=>[]];
- if (DBA::isResult($r)) {
- foreach ($r as $rr) {
- $photo = [];
- $photo['id'] = $rr['resource-id'];
- $photo['album'] = $rr['album'];
- $photo['filename'] = $rr['filename'];
- $photo['type'] = $rr['type'];
- $thumb = DI::baseUrl() . "/photo/" . $rr['resource-id'] . "-" . $rr['scale'] . "." . $typetoext[$rr['type']];
- $photo['created'] = $rr['created'];
- $photo['edited'] = $rr['edited'];
- $photo['desc'] = $rr['desc'];
-
- if ($type == "xml") {
- $data['photo'][] = ["@attributes" => $photo, "1" => $thumb];
- } else {
- $photo['thumb'] = $thumb;
- $data['photo'][] = $photo;
- }
- }
- }
- return BaseApi::formatData("photos", $type, $data);
-}
-
-/**
- * upload a new photo or change an existing photo
- *
- * @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
- * @return string|array
- * @throws BadRequestException
- * @throws ForbiddenException
- * @throws ImagickException
- * @throws InternalServerErrorException
- * @throws NotFoundException
- */
-function api_fr_photo_create_update($type)
-{
- if (api_user() === false) {
- throw new ForbiddenException();
- }
- // input params
- $photo_id = $_REQUEST['photo_id'] ?? null;
- $desc = $_REQUEST['desc'] ?? null;
- $album = $_REQUEST['album'] ?? null;
- $album_new = $_REQUEST['album_new'] ?? null;
- $allow_cid = $_REQUEST['allow_cid'] ?? null;
- $deny_cid = $_REQUEST['deny_cid' ] ?? null;
- $allow_gid = $_REQUEST['allow_gid'] ?? null;
- $deny_gid = $_REQUEST['deny_gid' ] ?? null;
- $visibility = !$allow_cid && !$deny_cid && !$allow_gid && !$deny_gid;
-
- // do several checks on input parameters
- // we do not allow calls without album string
- if ($album == null) {
- throw new BadRequestException("no albumname specified");
- }
- // if photo_id == null --> we are uploading a new photo
- if ($photo_id == null) {
- $mode = "create";
-
- // error if no media posted in create-mode
- if (empty($_FILES['media'])) {
- // Output error
- throw new BadRequestException("no media data submitted");
- }
-
- // album_new will be ignored in create-mode
- $album_new = "";
- } else {
- $mode = "update";
-
- // check if photo is existing in databasei
- if (!Photo::exists(['resource-id' => $photo_id, 'uid' => api_user(), 'album' => $album])) {
- throw new BadRequestException("photo not available");
- }
- }
-
- // checks on acl strings provided by clients
- $acl_input_error = false;
- $acl_input_error |= check_acl_input($allow_cid);
- $acl_input_error |= check_acl_input($deny_cid);
- $acl_input_error |= check_acl_input($allow_gid);
- $acl_input_error |= check_acl_input($deny_gid);
- if ($acl_input_error) {
- throw new BadRequestException("acl data invalid");
- }
- // now let's upload the new media in create-mode
- if ($mode == "create") {
- $media = $_FILES['media'];
- $data = save_media_to_database("photo", $media, $type, $album, trim($allow_cid), trim($deny_cid), trim($allow_gid), trim($deny_gid), $desc, Photo::DEFAULT, $visibility);
-
- // return success of updating or error message
- if (!is_null($data)) {
- return BaseApi::formatData("photo_create", $type, $data);
- } else {
- throw new InternalServerErrorException("unknown error - uploading photo failed, see Friendica log for more information");
- }
- }
-
- // now let's do the changes in update-mode
- if ($mode == "update") {
- $updated_fields = [];
-
- if (!is_null($desc)) {
- $updated_fields['desc'] = $desc;
- }
-
- if (!is_null($album_new)) {
- $updated_fields['album'] = $album_new;
- }
-
- if (!is_null($allow_cid)) {
- $allow_cid = trim($allow_cid);
- $updated_fields['allow_cid'] = $allow_cid;
- }
-
- if (!is_null($deny_cid)) {
- $deny_cid = trim($deny_cid);
- $updated_fields['deny_cid'] = $deny_cid;
- }
-
- if (!is_null($allow_gid)) {
- $allow_gid = trim($allow_gid);
- $updated_fields['allow_gid'] = $allow_gid;
- }
-
- if (!is_null($deny_gid)) {
- $deny_gid = trim($deny_gid);
- $updated_fields['deny_gid'] = $deny_gid;
- }
-
- $result = false;
- if (count($updated_fields) > 0) {
- $nothingtodo = false;
- $result = Photo::update($updated_fields, ['uid' => api_user(), 'resource-id' => $photo_id, 'album' => $album]);
- } else {
- $nothingtodo = true;
- }
-
- if (!empty($_FILES['media'])) {
- $nothingtodo = false;
- $media = $_FILES['media'];
- $data = save_media_to_database("photo", $media, $type, $album, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $desc, Photo::DEFAULT, $visibility, $photo_id);
- if (!is_null($data)) {
- return BaseApi::formatData("photo_update", $type, $data);
- }
- }
-
- // return success of updating or error message
- if ($result) {
- $answer = ['result' => 'updated', 'message' => 'Image id `' . $photo_id . '` has been updated.'];
- return BaseApi::formatData("photo_update", $type, ['$result' => $answer]);
- } else {
- if ($nothingtodo) {
- $answer = ['result' => 'cancelled', 'message' => 'Nothing to update for image id `' . $photo_id . '`.'];
- return BaseApi::formatData("photo_update", $type, ['$result' => $answer]);
- }
- throw new InternalServerErrorException("unknown error - update photo entry in database failed");
- }
- }
- throw new InternalServerErrorException("unknown error - this error on uploading or updating a photo should never happen");
-}
-
-/**
- * delete a single photo from the database through api
- *
- * @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
- * @return string|array
- * @throws BadRequestException
- * @throws ForbiddenException
- * @throws InternalServerErrorException
- */
-function api_fr_photo_delete($type)
-{
- if (api_user() === false) {
- throw new ForbiddenException();
- }
-
- // input params
- $photo_id = $_REQUEST['photo_id'] ?? null;
-
- // do several checks on input parameters
- // we do not allow calls without photo id
- if ($photo_id == null) {
- throw new BadRequestException("no photo_id specified");
- }
-
- // check if photo is existing in database
- if (!Photo::exists(['resource-id' => $photo_id, 'uid' => api_user()])) {
- throw new BadRequestException("photo not available");
- }
-
- // now we can perform on the deletion of the photo
- $result = Photo::delete(['uid' => api_user(), 'resource-id' => $photo_id]);
-
- // return success of deletion or error message
- if ($result) {
- // 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)
- $condition = ['uid' => api_user(), 'resource-id' => $photo_id, 'type' => 'photo'];
- Item::deleteForUser($condition, api_user());
-
- $result = ['result' => 'deleted', 'message' => 'photo with id `' . $photo_id . '` has been deleted from server.'];
- return BaseApi::formatData("photo_delete", $type, ['$result' => $result]);
- } else {
- throw new InternalServerErrorException("unknown error on deleting photo from database table");
- }
-}
-
-
-/**
- * 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|array
- * @throws BadRequestException
- * @throws ForbiddenException
- * @throws InternalServerErrorException
- * @throws NotFoundException
- */
-function api_fr_photo_detail($type)
-{
- if (api_user() === false) {
- throw new ForbiddenException();
- }
- if (empty($_REQUEST['photo_id'])) {
- throw new BadRequestException("No photo id.");
- }
-
- $scale = (!empty($_REQUEST['scale']) ? intval($_REQUEST['scale']) : false);
- $photo_id = $_REQUEST['photo_id'];
-
- // prepare json/xml output with data from database for the requested photo
- $data = prepare_photo_data($type, $scale, $photo_id);
-
- return BaseApi::formatData("photo_detail", $type, $data);
-}
-
-
-/**
- * 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|array
- * @throws BadRequestException
- * @throws ForbiddenException
- * @throws ImagickException
- * @throws InternalServerErrorException
- * @throws NotFoundException
- * @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)
-{
- if (api_user() === false) {
- throw new ForbiddenException();
- }
- // input params
- $profile_id = $_REQUEST['profile_id'] ?? 0;
-
- // error if image data is missing
- if (empty($_FILES['image'])) {
- throw new BadRequestException("no media data submitted");
- }
-
- // check if specified profile id is valid
- if ($profile_id != 0) {
- $profile = DBA::selectFirst('profile', ['is-default'], ['uid' => api_user(), 'id' => $profile_id]);
- // error message if specified profile id is not in database
- if (!DBA::isResult($profile)) {
- throw new BadRequestException("profile_id not available");
- }
- $is_default_profile = $profile['is-default'];
- } else {
- $is_default_profile = 1;
- }
-
- // get mediadata from image or media (Twitter call api/account/update_profile_image provides image)
- $media = null;
- if (!empty($_FILES['image'])) {
- $media = $_FILES['image'];
- } elseif (!empty($_FILES['media'])) {
- $media = $_FILES['media'];
- }
- // save new profile image
- $data = save_media_to_database("profileimage", $media, $type, DI::l10n()->t(Photo::PROFILE_PHOTOS), "", "", "", "", "", Photo::USER_AVATAR);
-
- // get filetype
- if (is_array($media['type'])) {
- $filetype = $media['type'][0];
- } else {
- $filetype = $media['type'];
- }
- if ($filetype == "image/jpeg") {
- $fileext = "jpg";
- } elseif ($filetype == "image/png") {
- $fileext = "png";
- } else {
- throw new InternalServerErrorException('Unsupported filetype');
- }
-
- // change specified profile or all profiles to the new resource-id
- if ($is_default_profile) {
- $condition = ["`profile` AND `resource-id` != ? AND `uid` = ?", $data['photo']['id'], api_user()];
- Photo::update(['profile' => false, 'photo-type' => Photo::DEFAULT], $condition);
- } else {
- $fields = ['photo' => DI::baseUrl() . '/photo/' . $data['photo']['id'] . '-4.' . $fileext,
- 'thumb' => DI::baseUrl() . '/photo/' . $data['photo']['id'] . '-5.' . $fileext];
- DBA::update('profile', $fields, ['id' => $_REQUEST['profile'], 'uid' => api_user()]);
- }
-
- Contact::updateSelfFromUserID(api_user(), true);
-
- // Update global directory in background
- Profile::publishUpdate(api_user());
-
- // output for client
- if ($data) {
- return api_account_verify_credentials($type);
- } else {
- // SaveMediaToDatabase failed for some reason
- throw new InternalServerErrorException("image upload failed");
- }
-}
-
-// place api-register for photoalbum calls before 'api/friendica/photo', otherwise this function is never reached
-api_register_func('api/friendica/photoalbum/delete', 'api_fr_photoalbum_delete', true, API_METHOD_DELETE);
-api_register_func('api/friendica/photoalbum/update', 'api_fr_photoalbum_update', true, API_METHOD_POST);
-api_register_func('api/friendica/photos/list', 'api_fr_photos_list', true);
-api_register_func('api/friendica/photo/create', 'api_fr_photo_create_update', true, API_METHOD_POST);
-api_register_func('api/friendica/photo/update', 'api_fr_photo_create_update', true, API_METHOD_POST);
-api_register_func('api/friendica/photo/delete', 'api_fr_photo_delete', true, API_METHOD_DELETE);
-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
- * @throws BadRequestException
- * @throws ForbiddenException
- * @throws ImagickException
- * @throws InternalServerErrorException
- * @throws UnauthorizedException
- */
-function api_account_update_profile($type)
-{
- $local_user = api_user();
- $api_user = api_get_user();
-
- if (!empty($_POST['name'])) {
- DBA::update('profile', ['name' => $_POST['name']], ['uid' => $local_user]);
- DBA::update('user', ['username' => $_POST['name']], ['uid' => $local_user]);
- Contact::update(['name' => $_POST['name']], ['uid' => $local_user, 'self' => 1]);
- Contact::update(['name' => $_POST['name']], ['id' => $api_user['id']]);
- }
-
- if (isset($_POST['description'])) {
- DBA::update('profile', ['about' => $_POST['description']], ['uid' => $local_user]);
- Contact::update(['about' => $_POST['description']], ['uid' => $local_user, 'self' => 1]);
- Contact::update(['about' => $_POST['description']], ['id' => $api_user['id']]);
- }
-
- Profile::publishUpdate($local_user);
-
- 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
- * @return bool
- * @throws Exception
- */
-function check_acl_input($acl_string)
-{
- if (empty($acl_string)) {
- return false;
- }
-
- $contact_not_found = false;
-
- // split <x><y><z> into array of cid's
- preg_match_all("/<[A-Za-z0-9]+>/", $acl_string, $array);
-
- // check for each cid if it is available on server
- $cid_array = $array[0];
- foreach ($cid_array as $cid) {
- $cid = str_replace("<", "", $cid);
- $cid = str_replace(">", "", $cid);
- $condition = ['id' => $cid, 'uid' => api_user()];
- $contact_not_found |= !DBA::exists('contact', $condition);
- }
- 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 $phototype
- * @param boolean $visibility
- * @param string $photo_id
- * @return array
- * @throws BadRequestException
- * @throws ForbiddenException
- * @throws ImagickException
- * @throws InternalServerErrorException
- * @throws NotFoundException
- * @throws UnauthorizedException
- */
-function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $desc, $phototype = 0, $visibility = false, $photo_id = null)
-{
- $visitor = 0;
- $src = "";
- $filetype = "";
- $filename = "";
- $filesize = 0;
-
- if (is_array($media)) {
- if (is_array($media['tmp_name'])) {
- $src = $media['tmp_name'][0];
- } else {
- $src = $media['tmp_name'];
- }
- if (is_array($media['name'])) {
- $filename = basename($media['name'][0]);
- } else {
- $filename = basename($media['name']);
- }
- if (is_array($media['size'])) {
- $filesize = intval($media['size'][0]);
- } else {
- $filesize = intval($media['size']);
- }
- if (is_array($media['type'])) {
- $filetype = $media['type'][0];
- } else {
- $filetype = $media['type'];
- }
- }
-
- $filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
-
- logger::info(
- "File upload src: " . $src . " - filename: " . $filename .
- " - size: " . $filesize . " - type: " . $filetype);
-
- // check if there was a php upload error
- if ($filesize == 0 && $media['error'] == 1) {
- throw new InternalServerErrorException("image size exceeds PHP config settings, file was rejected by server");
- }
- // check against max upload size within Friendica instance
- $maximagesize = DI::config()->get('system', 'maximagesize');
- if ($maximagesize && ($filesize > $maximagesize)) {
- $formattedBytes = Strings::formatBytes($maximagesize);
- throw new InternalServerErrorException("image size exceeds Friendica config setting (uploaded size: $formattedBytes)");
- }
-
- // create Photo instance with the data of the image
- $imagedata = @file_get_contents($src);
- $Image = new Image($imagedata, $filetype);
- if (!$Image->isValid()) {
- throw new InternalServerErrorException("unable to process image data");
- }
-
- // check orientation of image
- $Image->orient($src);
- @unlink($src);
-
- // check max length of images on server
- $max_length = DI::config()->get('system', 'max_image_length');
- if ($max_length > 0) {
- $Image->scaleDown($max_length);
- logger::info("File upload: Scaling picture to new size " . $max_length);
- }
- $width = $Image->getWidth();
- $height = $Image->getHeight();
-
- // create a new resource-id if not already provided
- $resource_id = ($photo_id == null) ? Photo::newResource() : $photo_id;
-
- if ($mediatype == "photo") {
- // upload normal image (scales 0, 1, 2)
- logger::info("photo upload: starting new photo upload");
-
- $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 0, Photo::DEFAULT, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
- if (!$r) {
- logger::notice("photo upload: image upload with scale 0 (original size) failed");
- }
- if ($width > 640 || $height > 640) {
- $Image->scaleDown(640);
- $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 1, Photo::DEFAULT, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
- if (!$r) {
- logger::notice("photo upload: image upload with scale 1 (640x640) failed");
- }
- }
-
- if ($width > 320 || $height > 320) {
- $Image->scaleDown(320);
- $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 2, Photo::DEFAULT, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
- if (!$r) {
- logger::notice("photo upload: image upload with scale 2 (320x320) failed");
- }
- }
- logger::info("photo upload: new photo upload ended");
- } elseif ($mediatype == "profileimage") {
- // upload profile image (scales 4, 5, 6)
- logger::info("photo upload: starting new profile image upload");
-
- if ($width > 300 || $height > 300) {
- $Image->scaleDown(300);
- $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 4, $phototype, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
- if (!$r) {
- logger::notice("photo upload: profile image upload with scale 4 (300x300) failed");
- }
- }
-
- if ($width > 80 || $height > 80) {
- $Image->scaleDown(80);
- $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 5, $phototype, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
- if (!$r) {
- logger::notice("photo upload: profile image upload with scale 5 (80x80) failed");
- }
- }
-
- if ($width > 48 || $height > 48) {
- $Image->scaleDown(48);
- $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 6, $phototype, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
- if (!$r) {
- logger::notice("photo upload: profile image upload with scale 6 (48x48) failed");
- }
- }
- $Image->__destruct();
- logger::info("photo upload: new profile image upload ended");
- }