88
99namespace App \Actions \RSS ;
1010
11+ use App \Constants \PhotoAlbum as PA ;
1112use App \Contracts \Exceptions \InternalLycheeException ;
13+ use App \Enum \SizeVariantType ;
1214use App \Exceptions \Internal \FrameworkException ;
1315use App \Models \Configs ;
16+ use App \Models \Extensions \HasUrlGenerator ;
17+ use App \Models \Extensions \UTCBasedTimes ;
1418use App \Models \Photo ;
1519use App \Policies \PhotoQueryPolicy ;
1620use Carbon \Exceptions \InvalidFormatException ;
1721use Carbon \Exceptions \UnitException ;
22+ use Illuminate \Contracts \Container \BindingResolutionException ;
1823use Illuminate \Support \Carbon ;
1924use Illuminate \Support \Collection ;
25+ use Illuminate \Support \Facades \DB ;
2026use Spatie \Feed \FeedItem ;
2127
28+ /**
29+ * @template T of object{id:string,title:string,description:?string,type:string,created_at:string,updated_at:string,album_id:string,album_title:string,short_path:string,filesize:int,storage_disk:string,size_variant_type:string,username:string}
30+ *
31+ * @package App\Actions\RSS
32+ */
2233class Generate
2334{
35+ use HasUrlGenerator;
36+ use UTCBasedTimes;
37+
2438 public function __construct (
2539 protected PhotoQueryPolicy $ photo_query_policy )
2640 {
2741 }
2842
29- private function create_link_to_page (Photo $ photo_model ): string
30- {
31- if ($ photo_model ->album_id !== null ) {
32- return url ('/gallery/ ' . $ photo_model ->album_id . '/ ' . $ photo_model ->id );
33- }
34-
35- return url ('/view?p= ' . $ photo_model ->id );
36- }
37-
38- private function toFeedItem (Photo $ photo_model ): FeedItem
43+ /**
44+ *
45+ * @param T $data
46+ * @return FeedItem
47+ * @throws BindingResolutionException
48+ */
49+ private function toFeedItem (object $ data ): FeedItem
3950 {
40- $ page_link = $ this ->create_link_to_page ($ photo_model );
41- $ size_variant = $ photo_model ->size_variants ->getOriginal ();
42- $ cat_arr = [];
43- if ($ photo_model ->album_id !== null ) {
44- $ cat_arr [] = $ photo_model ->album ->title ;
45- }
51+ $ page_link = route ('gallery ' , ['albumId ' => $ data ->album_id , 'photoId ' => $ data ->id ]);
4652 $ feed_item = [
4753 'id ' => $ page_link ,
48- 'title ' => $ photo_model ->title ,
49- 'summary ' => $ photo_model ->description ?? '' ,
50- 'updated ' => $ photo_model -> updated_at ,
54+ 'title ' => $ data ->title ,
55+ 'summary ' => $ data ->description ?? '' ,
56+ 'updated ' => $ this -> asDateTime ( $ data -> updated_at ) ,
5157 'link ' => $ page_link ,
52- 'enclosure ' => $ size_variant -> url ,
53- 'enclosureType ' => $ photo_model ->type ,
54- 'enclosureLength ' => $ size_variant ->filesize ,
55- 'authorName ' => $ photo_model -> owner ->username ,
56- 'category ' => $ cat_arr ,
58+ 'enclosure ' => self :: pathToUrl ( $ data -> short_path , $ data -> storage_disk , SizeVariantType:: ORIGINAL ) ,
59+ 'enclosureType ' => $ data ->type ,
60+ 'enclosureLength ' => $ data ->filesize ,
61+ 'authorName ' => $ data ->username ,
62+ 'category ' => [ $ data -> album_title ] ,
5763 ];
5864
5965 return FeedItem::create ($ feed_item );
@@ -74,17 +80,36 @@ public function do(): Collection
7480 throw new FrameworkException ('Date/Time component (Carbon) ' , $ e );
7581 }
7682
77- /** @var Collection<int,Photo > $photos */
83+ /** @var Collection<int,T > $photos */
7884 $ photos = $ this ->photo_query_policy
7985 ->applySearchabilityFilter (
80- query: Photo::query ()-> with ([ ' albums ' , ' owner ' , ' size_variants ' ]) ,
86+ query: Photo::query (),
8187 origin: null ,
8288 include_nsfw: !Configs::getValueAsBool ('hide_nsfw_in_rss ' )
8389 )
90+ ->joinSub (DB ::table (PA ::PHOTO_ALBUM ), 'outer_ ' .PA ::PHOTO_ALBUM , 'photos.id ' , '= ' , 'outer_ ' .PA ::PHOTO_ID )
91+ ->join ('base_albums ' , 'base_albums.id ' , '= ' , 'outer_ ' .PA ::ALBUM_ID )
92+ ->join ('size_variants ' , 'size_variants.photo_id ' , '= ' , 'photos.id ' )
93+ ->join ('users ' , 'users.id ' , '= ' , 'photos.owner_id ' )
94+ ->where ('size_variants.type ' , '= ' , SizeVariantType::ORIGINAL ->value )
95+ ->select ([
96+ 'photos.id ' ,
97+ 'photos.title ' ,
98+ 'photos.description ' ,
99+ 'photos.type ' ,
100+ 'photos.updated_at ' ,
101+ 'outer_ ' .PA ::ALBUM_ID ,
102+ 'base_albums.title as album_title ' ,
103+ 'size_variants.short_path ' ,
104+ 'size_variants.filesize ' ,
105+ 'size_variants.storage_disk ' ,
106+ 'users.username ' ]
107+ )
84108 ->where ('photos.created_at ' , '>= ' , $ now_minus )
85109 ->limit ($ rss_max )
110+ ->toBase () // We use toBase() to avoid the use of the Eloquent casts etc.
86111 ->get ();
87112
88- return $ photos ->map (fn (Photo $ p ) => $ this ->toFeedItem ($ p ));
113+ return $ photos ->map (fn (object $ p ) => $ this ->toFeedItem ($ p ));
89114 }
90115}
0 commit comments