diff --git a/src/Content/Item.php b/src/Content/Item.php
index 2e86fb82d..e74ca846d 100644
--- a/src/Content/Item.php
+++ b/src/Content/Item.php
@@ -925,7 +925,7 @@ class Item
 
 		// embedded bookmark or attachment in post? set bookmark flag
 		$data = BBCode::getAttachmentData($post['body']);
-		if ((preg_match_all("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", $post['body'], $match, PREG_SET_ORDER) || isset($data['type']))
+		if ((preg_match_all("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", $post['body'], $match, PREG_SET_ORDER) || !empty($data['type']))
 			&& ($post['post-type'] != ItemModel::PT_PERSONAL_NOTE)) {
 			$post['post-type'] = ItemModel::PT_PAGE;
 			$post['object-type'] = Activity\ObjectType::BOOKMARK;
@@ -934,16 +934,6 @@ class Item
 		// Setting the object type if not defined before
 		if (empty($post['object-type'])) {
 			$post['object-type'] = ($post['gravity'] == ItemModel::GRAVITY_PARENT) ? Activity\ObjectType::NOTE : Activity\ObjectType::COMMENT;
-
-			$objectdata = BBCode::getAttachedData($post['body']);
-
-			if ($objectdata['type'] == 'link') {
-				$post['object-type'] = Activity\ObjectType::BOOKMARK;
-			} elseif ($objectdata['type'] == 'video') {
-				$post['object-type'] = Activity\ObjectType::VIDEO;
-			} elseif ($objectdata['type'] == 'photo') {
-				$post['object-type'] = Activity\ObjectType::IMAGE;
-			}
 		}
 		return $post;
 	}
diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index 949f9d9cf..9651e91cf 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -74,77 +74,6 @@ class BBCode
 	const PREVIEW_LARGE    = 2;
 	const PREVIEW_SMALL    = 3;
 
-	/**
-	 * Fetches attachment data that were generated the old way
-	 *
-	 * @param string $body Message body
-	 * @return array
-	 *                     'type' -> Message type ('link', 'video', 'photo')
-	 *                     'text' -> Text before the shared message
-	 *                     'after' -> Text after the shared message
-	 *                     'image' -> Preview image of the message
-	 *                     'url' -> Url to the attached message
-	 *                     'title' -> Title of the attachment
-	 *                     'description' -> Description of the attachment
-	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-	 */
-	private static function getOldAttachmentData(string $body): array
-	{
-		$post = [];
-
-		// Simplify image codes
-		$body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
-
-		if (preg_match_all("(\[class=(.*?)\](.*?)\[\/class\])ism", $body, $attached, PREG_SET_ORDER)) {
-			foreach ($attached as $data) {
-				if (!in_array($data[1], ['type-link', 'type-video', 'type-photo'])) {
-					continue;
-				}
-
-				$post['type'] = substr($data[1], 5);
-
-				$pos = strpos($body, $data[0]);
-				if ($pos > 0) {
-					$post['text'] = trim(substr($body, 0, $pos));
-					$post['after'] = trim(substr($body, $pos + strlen($data[0])));
-				} else {
-					$post['text'] = trim(str_replace($data[0], '', $body));
-					$post['after'] = '';
-				}
-
-				$attacheddata = $data[2];
-
-				if (preg_match("/\[img\](.*?)\[\/img\]/ism", $attacheddata, $matches)) {
-
-					$picturedata = Images::getInfoFromURLCached($matches[1]);
-
-					if ($picturedata) {
-						if (($picturedata[0] >= 500) && ($picturedata[0] >= $picturedata[1])) {
-							$post['image'] = $matches[1];
-						} else {
-							$post['preview'] = $matches[1];
-						}
-					}
-				}
-
-				if (preg_match("/\[bookmark\=(.*?)\](.*?)\[\/bookmark\]/ism", $attacheddata, $matches)) {
-					$post['url'] = $matches[1];
-					$post['title'] = $matches[2];
-				}
-				if (!empty($post['url']) && (in_array($post['type'], ['link', 'video']))
-					&& preg_match("/\[url\=(.*?)\](.*?)\[\/url\]/ism", $attacheddata, $matches)) {
-					$post['url'] = $matches[1];
-				}
-
-				// Search for description
-				if (preg_match("/\[quote\](.*?)\[\/quote\]/ism", $attacheddata, $matches)) {
-					$post['description'] = $matches[1];
-				}
-			}
-		}
-		return $post;
-	}
-
 	/**
 	 * Fetches attachment data that were generated with the "attachment" element
 	 *
@@ -178,7 +107,7 @@ class BBCode
 
 		if (!preg_match("/(.*)\[attachment(.*?)\](.*?)\[\/attachment\](.*)/ism", $body, $match)) {
 			DI::profiler()->stopRecording();
-			return self::getOldAttachmentData($body);
+			return [];
 		}
 
 		$attributes = $match[2];
@@ -253,183 +182,6 @@ class BBCode
 		return $data;
 	}
 
-	public static function getAttachedData(string $body, array $item = []): array
-	{
-		/*
-		- text:
-		- type: link, video, photo
-		- title:
-		- url:
-		- image:
-		- description:
-		- (thumbnail)
-		*/
-
-		DI::profiler()->startRecording('rendering');
-		$has_title = !empty($item['title']);
-		$plink = $item['plink'] ?? '';
-		$post = self::getAttachmentData($body);
-
-		// Get all linked images with alternative image description
-		if (preg_match_all("/\[img=(http[^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
-			foreach ($pictures as $picture) {
-				if ($id = Photo::getIdForName($picture[1])) {
-					$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => $picture[2], 'id' => $id];
-				} else {
-					$post['remote_images'][] = ['url' => $picture[1], 'description' => $picture[2]];
-				}
-			}
-			if (!empty($post['images']) && !empty($post['images'][0]['description'])) {
-				$post['image_description'] = $post['images'][0]['description'];
-			}
-		}
-
-		if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
-			foreach ($pictures as $picture) {
-				if ($id = Photo::getIdForName($picture[1])) {
-					$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => '', 'id' => $id];
-				} else {
-					$post['remote_images'][] = ['url' => $picture[1], 'description' => ''];
-				}
-			}
-		}
-
-		if (!isset($post['type'])) {
-			$post['text'] = $body;
-		}
-
-		// Simplify image codes
-		$post['text'] = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $post['text']);
-		$post['text'] = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", '[img]$1[/img]', $post['text']);
-
-		// if nothing is found, it maybe having an image.
-		if (!isset($post['type'])) {
-			if (preg_match_all("#\[url=([^\]]+?)\]\s*\[img\]([^\[]+?)\[/img\]\s*\[/url\]#ism", $post['text'], $pictures, PREG_SET_ORDER)) {
-				if ((count($pictures) == 1) && !$has_title && !Photo::isLocal($pictures[0][2])) {
-					if (!empty($item['object-type']) && ($item['object-type'] == Activity\ObjectType::IMAGE)) {
-						// Replace the preview picture with the real picture
-						$url = str_replace('-1.', '-0.', $pictures[0][2]);
-						$data = ['url' => $url, 'type' => 'photo'];
-					} else {
-						// Checking, if the link goes to a picture
-						$data = ParseUrl::getSiteinfoCached($pictures[0][1]);
-					}
-
-					// Workaround:
-					// Sometimes photo posts to the own album are not detected at the start.
-					// So we seem to cannot use the cache for these cases. That's strange.
-					if (($data['type'] != 'photo') && strstr($pictures[0][1], '/photos/')) {
-						$data = ParseUrl::getSiteinfo($pictures[0][1]);
-					}
-
-					if ($data['type'] == 'photo') {
-						$post['type'] = 'photo';
-						if (isset($data['images'][0])) {
-							$post['image'] = $data['images'][0]['src'];
-							$post['url'] = $data['url'];
-						} else {
-							$post['image'] = $data['url'];
-						}
-
-						$post['preview'] = $pictures[0][2];
-						$post['text'] = trim(str_replace($pictures[0][0], '', $post['text']));
-					} else {
-						$imgdata = Images::getInfoFromURLCached($pictures[0][1]);
-						if (($imgdata) && substr($imgdata['mime'], 0, 6) == 'image/') {
-							$post['type'] = 'photo';
-							$post['image'] = $pictures[0][1];
-							$post['preview'] = $pictures[0][2];
-							$post['text'] = trim(str_replace($pictures[0][0], '', $post['text']));
-						}
-					}
-				} elseif (count($pictures) > 0) {
-					if (count($pictures) > 4) {
-						$post['type'] = 'link';
-						$post['url'] = $plink;
-					} else {
-						$post['type'] = 'photo';
-					}
-
-					$post['image'] = $pictures[0][2];
-
-					foreach ($pictures as $picture) {
-						$post['text'] = trim(str_replace($picture[0], '', $post['text']));
-					}
-				}
-			} elseif (preg_match_all("(\[img\](.*?)\[\/img\])ism", $post['text'], $pictures, PREG_SET_ORDER)) {
-				if ($has_title) {
-					$post['type'] = 'link';
-					$post['url'] = $plink;
-				} else {
-					$post['type'] = 'photo';
-				}
-
-				$post['image'] = $pictures[0][1];
-				foreach ($pictures as $picture) {
-					$post['text'] = trim(str_replace($picture[0], '', $post['text']));
-				}
-			}
-
-			// Test for the external links
-			preg_match_all("(\[url\](.*?)\[\/url\])ism", $post['text'], $links1, PREG_SET_ORDER);
-			preg_match_all("(\[url\=(.*?)\].*?\[\/url\])ism", $post['text'], $links2, PREG_SET_ORDER);
-
-			$links = array_merge($links1, $links2);
-
-			// If there is only a single one, then use it.
-			// This should cover link posts via API.
-			if ((count($links) == 1) && !isset($post['preview']) && !$has_title) {
-				$post['type'] = 'link';
-				$post['url'] = $links[0][1];
-			}
-
-			// Simplify "video" element
-			$post['text'] = preg_replace('(\[video.*?\ssrc\s?=\s?([^\s\]]+).*?\].*?\[/video\])ism', '[video]$1[/video]', $post['text']);
-
-			// Now count the number of external media links
-			preg_match_all("(\[vimeo\](.*?)\[\/vimeo\])ism", $post['text'], $links1, PREG_SET_ORDER);
-			preg_match_all("(\[youtube\\](.*?)\[\/youtube\\])ism", $post['text'], $links2, PREG_SET_ORDER);
-			preg_match_all("(\[video\\](.*?)\[\/video\\])ism", $post['text'], $links3, PREG_SET_ORDER);
-			preg_match_all("(\[audio\\](.*?)\[\/audio\\])ism", $post['text'], $links4, PREG_SET_ORDER);
-
-			// Add them to the other external links
-			$links = array_merge($links, $links1, $links2, $links3, $links4);
-
-			// Are there more than one?
-			if (count($links) > 1) {
-				// The post will be the type "text", which means a blog post
-				unset($post['type']);
-				$post['url'] = $plink;
-			}
-
-			if (!isset($post['type'])) {
-				$post['type'] = 'text';
-			}
-
-			if (($post['type'] == 'photo') && empty($post['images']) && !empty($post['remote_images'])) {
-				$post['images'] = $post['remote_images'];
-				$post['image'] = $post['images'][0]['url'];
-				if (!empty($post['images']) && !empty($post['images'][0]['description'])) {
-					$post['image_description'] = $post['images'][0]['description'];
-				}
-			}
-			unset($post['remote_images']);
-		} elseif (isset($post['url']) && ($post['type'] == 'video')) {
-			$data = ParseUrl::getSiteinfoCached($post['url']);
-
-			if (isset($data['images'][0])) {
-				$post['image'] = $data['images'][0]['src'];
-			}
-		} elseif (preg_match_all("#\[url=([^\]]+?)\]\s*\[img\]([^\[]+?)\[/img\]\s*\[/url\]#ism", $post['text'], $pictures, PREG_SET_ORDER)) {
-			foreach ($pictures as $picture) {
-				$post['text'] = trim(str_replace($picture[0], '', $post['text']));
-			}
-		}
-
-		DI::profiler()->stopRecording();
-		return $post;
-	}
-
 	/**
 	 * Remove [attachment] BBCode and replaces it with a regular [url]
 	 *
diff --git a/src/Content/Text/Plaintext.php b/src/Content/Text/Plaintext.php
index 9a7435f5b..0866e476c 100644
--- a/src/Content/Text/Plaintext.php
+++ b/src/Content/Text/Plaintext.php
@@ -129,7 +129,7 @@ class Plaintext
 		$body = BBCode::stripAbstract($body);
 
 		// At first look at data that is attached via "type-..." stuff
-		$post = BBCode::getAttachedData($body, $item);
+		$post = BBCode::getAttachmentData($body, $item);
 
 		if (($item['title'] != '') && ($post['text'] != '')) {
 			$post['text'] = trim($item['title'] . "\n\n" . $post['text']);
diff --git a/src/Factory/Api/Mastodon/Card.php b/src/Factory/Api/Mastodon/Card.php
index dc46a7780..f6f6e3b67 100644
--- a/src/Factory/Api/Mastodon/Card.php
+++ b/src/Factory/Api/Mastodon/Card.php
@@ -39,45 +39,40 @@ class Card extends BaseFactory
 	 */
 	public function createFromUriId(int $uriId, array $history = []): \Friendica\Object\Api\Mastodon\Card
 	{
-		$item = Post::selectFirst(['body'], ['uri-id' => $uriId]);
-		if (!empty($item['body'])) {
-			$data = BBCode::getAttachmentData($item['body']);
-		} else {
-			$data = [];
+		$media = Post\Media::getByURIId($uriId, [Post\Media::HTML]);
+		if (empty($media) && empty($media[0]['description']) && !empty($media[0]['image']) && !empty($media[0]['preview'])) {
+			return new \Friendica\Object\Api\Mastodon\Card([], $history);
 		}
 
-		foreach (Post\Media::getByURIId($uriId, [Post\Media::HTML]) as $attached) {
-			if ((empty($data['url']) || Strings::compareLink($data['url'], $attached['url'])) &&
-				(!empty($attached['description']) || !empty($attached['image']) || !empty($attached['preview']))) {
-				$parts = parse_url($attached['url']);
-				if (!empty($parts['scheme']) && !empty($parts['host'])) {
-					if (empty($attached['publisher-name'])) {
-						$attached['publisher-name'] = $parts['host'];
-					}
-					if (empty($attached['publisher-url']) || empty(parse_url($attached['publisher-url'], PHP_URL_SCHEME))) {
-						$attached['publisher-url'] = $parts['scheme'] . '://' . $parts['host'];
+		$parts = parse_url($media[0]['url']);
+		if (!empty($parts['scheme']) && !empty($parts['host'])) {
+			if (empty($media[0]['publisher-name'])) {
+				$media[0]['publisher-name'] = $parts['host'];
+			}
+			if (empty($media[0]['publisher-url']) || empty(parse_url($media[0]['publisher-url'], PHP_URL_SCHEME))) {
+				$media[0]['publisher-url'] = $parts['scheme'] . '://' . $parts['host'];
 
-						if (!empty($parts['port'])) {
-							$attached['publisher-url'] .= ':' . $parts['port'];
-						}
-					}
+				if (!empty($parts['port'])) {
+					$media[0]['publisher-url'] .= ':' . $parts['port'];
 				}
-
-				$data['url']           = $attached['url'];
-				$data['title']         = $attached['name'];
-				$data['description']   = $attached['description'];
-				$data['type']          = 'link';
-				$data['author_name']   = $attached['author-name'];
-				$data['author_url']    = $attached['author-url'];
-				$data['provider_name'] = $attached['publisher-name'];
-				$data['provider_url']  = $attached['publisher-url'];
-				$data['image']         = $attached['preview'];
-				$data['width']         = $attached['preview-width'];
-				$data['height']        = $attached['preview-height'];
-				$data['blurhash']      = $attached['blurhash'];
 			}
 		}
 
+		$data = [];
+
+		$data['url']           = $media[0]['url'];
+		$data['title']         = $media[0]['name'];
+		$data['description']   = $media[0]['description'];
+		$data['type']          = 'link';
+		$data['author_name']   = $media[0]['author-name'];
+		$data['author_url']    = $media[0]['author-url'];
+		$data['provider_name'] = $media[0]['publisher-name'];
+		$data['provider_url']  = $media[0]['publisher-url'];
+		$data['image']         = $media[0]['preview'];
+		$data['width']         = $media[0]['preview-width'];
+		$data['height']        = $media[0]['preview-height'];
+		$data['blurhash']      = $media[0]['blurhash'];
+
 		return new \Friendica\Object\Api\Mastodon\Card($data, $history);
 	}
 }
diff --git a/src/Model/Post/Media.php b/src/Model/Post/Media.php
index 5dfb227d6..ee74ee02b 100644
--- a/src/Model/Post/Media.php
+++ b/src/Model/Post/Media.php
@@ -896,6 +896,13 @@ class Media
 		return $body;
 	}
 
+	/**
+	 * Add an [attachment] element to the body for a given uri-id with a HTML media element
+	 *
+	 * @param integer $uriid
+	 * @param string $body
+	 * @return string
+	 */
 	public static function addHTMLAttachmentToBody(int $uriid, string $body): string
 	{
 		if (preg_match("/.*(\[attachment.*?\].*?\[\/attachment\]).*/ism", $body, $match)) {
@@ -929,6 +936,13 @@ class Media
 		return $body;
 	}
 
+	/**
+	 * Add a link to the body for a given uri-id with a HTML media element
+	 *
+	 * @param integer $uriid
+	 * @param string $body
+	 * @return string
+	 */
 	public static function addHTMLLinkToBody(int $uriid, string $body): string
 	{
 		$links = self::getByURIId($uriid, [self::HTML]);
@@ -947,6 +961,12 @@ class Media
 		}
 	}
 
+	/**
+	 * Add an [attachment] element to the body and a link to raw-body for a given uri-id with a HTML media element
+	 *
+	 * @param array $item
+	 * @return array
+	 */
 	public static function addHTMLAttachmentToItem(array $item): array
 	{
 		if (($item['gravity'] == Item::GRAVITY_ACTIVITY) || empty($item['uri-id'])) {
diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php
index 91eb1cc2c..160667681 100644
--- a/src/Protocol/Diaspora.php
+++ b/src/Protocol/Diaspora.php
@@ -3330,9 +3330,9 @@ class Diaspora
 
 			// Fetch the title from an attached link - if there is one
 			if (empty($item['title']) && DI::pConfig()->get($owner['uid'], 'system', 'attach_link_title')) {
-				$page_data = BBCode::getAttachmentData($item['body']);
-				if (!empty($page_data['type']) && !empty($page_data['title']) && ($page_data['type'] == 'link')) {
-					$title = $page_data['title'];
+				$media = Post\Media::getByURIId($item['uri-id'], [Post\Media::HTML]);
+				if (!empty($media) && !empty($media[0]['name']) && ($media[0]['name'] != $media[0]['url'])) {
+					$title = $media[0]['name'];
 				}
 			}
 
diff --git a/src/Protocol/Feed.php b/src/Protocol/Feed.php
index 625305161..f9ea91c77 100644
--- a/src/Protocol/Feed.php
+++ b/src/Protocol/Feed.php
@@ -1211,9 +1211,9 @@ class Feed
 		}
 
 		// Fetch information about the post
-		$siteinfo = BBCode::getAttachedData($item['body']);
-		if (isset($siteinfo['title'])) {
-			return $siteinfo['title'];
+		$media = Post\Media::getByURIId($item['uri-id'], [Post\Media::HTML]);
+		if (!empty($media) && !empty($media[0]['name']) && ($media[0]['name'] != $media[0]['url'])) {
+			return $media[0]['name'];
 		}
 
 		// If no bookmark is found then take the first line