4
0
Эх сурвалжийг харах

Fix only the last <media:credit> being written to the RSS output (#9174)

The loop building the media credits assigned instead of appending, so an enclosure with several credits only kept the last one.

`app/views/index/rss.phtml` builds the `<media:credit>` elements for an enclosure in a loop, but assigns instead of appends:

```php
$mediaCredits = '';
foreach ($credits as $credit) {
    $mediaCredits = '<media:credit>' . $credit . '</media:credit>';
}
```

So an enclosure with three credits emits only the last one. Every iteration throws away what the previous one built.

This came in with #6272 ("Allow multiple authors on enclosures", which closed #5066). Parsing and display got multi-credit support, but FreshRSS's own generated RSS still passes on a single credit, so a downstream reader subscribing to a FreshRSS feed sees the same symptom #5066 described.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
TowyTowy 2 долоо хоног өмнө
parent
commit
95842d81c1

+ 1 - 1
app/views/index/rss.phtml

@@ -83,7 +83,7 @@ foreach ($this->entries as $item) {
 					}
 					$mediaCredits = '';
 					foreach ($credits as $credit) {
-						$mediaCredits = '<media:credit>' . $credit . '</media:credit>';
+						$mediaCredits .= '<media:credit>' . $credit . '</media:credit>';
 					}
 
 					// https://www.rssboard.org/media-rss

+ 49 - 0
tests/app/Views/rssViewTest.php

@@ -0,0 +1,49 @@
+<?php
+declare(strict_types=1);
+
+final class rssViewTest extends \PHPUnit\Framework\TestCase {
+
+	#[\Override]
+	public static function setUpBeforeClass(): void {
+		// `FreshRSS_View` needs a system configuration; the shipped defaults are enough to render a feed.
+		Minz_Configuration::register('system', FRESHRSS_PATH . '/config.default.php', FRESHRSS_PATH . '/config.default.php');
+	}
+
+	/** @param array<string,mixed> $enclosure */
+	private static function renderEntryWithEnclosure(array $enclosure): string {
+		$entry = new FreshRSS_Entry(1, 'guid', 'Title', '', 'Content', 'https://example.net/article', 1700000000);
+		$entry->_attribute('enclosures', [$enclosure]);
+
+		$view = new FreshRSS_View();
+		$view->_path('index/rss.phtml');
+		$view->internal_rendering = true;
+		$view->rss_title = 'Test';
+		$view->rss_url = 'https://example.net/rss';
+		$view->html_url = 'https://example.net/';
+		$view->description = 'Test';
+		$view->entries = [$entry];
+
+		return $view->renderToString();
+	}
+
+	/** An enclosure with several `<media:credit>` must keep them all, see https://github.com/FreshRSS/FreshRSS/issues/5066 */
+	public function test_rss_multipleEnclosureCredits(): void {
+		$rss = self::renderEntryWithEnclosure([
+			'url' => 'https://example.net/audio.mp3',
+			'type' => 'audio/mpeg',
+			'credit' => ['Alice', 'Bob', 'Carol'],
+		]);
+		self::assertStringContainsString(
+			'<media:credit>Alice</media:credit><media:credit>Bob</media:credit><media:credit>Carol</media:credit>', $rss);
+	}
+
+	/** Entries older than FreshRSS 1.24 store a single credit as a string instead of an array */
+	public function test_rss_legacySingleEnclosureCredit(): void {
+		$rss = self::renderEntryWithEnclosure([
+			'url' => 'https://example.net/audio.mp3',
+			'type' => 'audio/mpeg',
+			'credit' => 'Alice',
+		]);
+		self::assertStringContainsString('<media:credit>Alice</media:credit>', $rss);
+	}
+}