From d43769dd98f352021cfec685a630d3d606d914fb Mon Sep 17 00:00:00 2001 From: Joel Male Date: Sat, 11 Apr 2026 08:37:43 +1000 Subject: [PATCH] refactor: strict types, typed props, split toXml/generate, custom exception --- .../MissingRequiredFieldException.php | 9 +++ src/LaravelFacebookFeed.php | 68 +++++++++---------- 2 files changed, 42 insertions(+), 35 deletions(-) create mode 100644 src/Exceptions/MissingRequiredFieldException.php diff --git a/src/Exceptions/MissingRequiredFieldException.php b/src/Exceptions/MissingRequiredFieldException.php new file mode 100644 index 0000000..6e163a4 --- /dev/null +++ b/src/Exceptions/MissingRequiredFieldException.php @@ -0,0 +1,9 @@ +title = $title; $feed->description = $description; $feed->link = $link; @@ -33,26 +35,20 @@ public static function init($title = null, $description = null, $link = null) return $feed; } - public function addItem(array $item): bool + public function addItem(array $item): void { - foreach ($this->requiredProductFields as $field) { - if (!isset($item[$field])) { - throw new \Exception("Required field '{$field}' is missing"); + foreach (self::REQUIRED_PRODUCT_FIELDS as $field) { + if (! isset($item[$field])) { + throw new MissingRequiredFieldException("Required field '{$field}' is missing"); } } - foreach ($item as $key => $value) { - $product[$key] = $value; - } - - $this->products[] = $product; - - return true; + $this->products[] = $item; } - public function generate() + public function toXml(): string { - $this->xml = [ + $data = [ 'rss' => [ '_attributes' => [ 'xmlns:g' => 'http://base.google.com/ns/1.0', @@ -62,23 +58,25 @@ public function generate() 'title' => $this->title, 'description' => $this->description, 'link' => $this->link, - ] - ] + ], + ], ]; foreach ($this->products as $key => $product) { - $this->xml['rss']['channel']['item_'.$key] = $product; + $data['rss']['channel']['item_' . $key] = $product; } - $xml = ArrayToXml::convert($this->xml, ''); + $xml = ArrayToXml::convert($data, ''); $xml = str_replace([' ', '', '', "\n", "\r", 'remove'], '', $xml); - $xml = preg_replace([ - "/item_[0-9][0-9][0-9][0-9]/", - "/item_[0-9][0-9][0-9]/", - "/item_[0-9][0-9]/", - "/item_[0-9]/", - ], "item", $xml); + // spatie/array-to-xml does not support repeated keys, so products are keyed as + // item_0, item_1, etc. and renamed back to tags here. + $xml = (string) preg_replace('/item_\d+/', 'item', $xml); - return response($xml)->header('Content-Type', 'text/xml'); + return $xml; + } + + public function generate(): Response + { + return ResponseFacade::make($this->toXml(), headers: ['Content-Type' => 'application/rss+xml']); } }