CodeWriteson Yanlış kullanmışsınız, şöyle kullanmanız lazım:
$news = News::firstOrCreate([
'site_name'=>'site2.com',
], [
'title'=>$item['title'],
'link' => $item['link'],
'img' => $item['img']
]);
Bu, şu demek: site_name değeri site2.com olan bir kayıt yoksa tüm değerler ile oluştur ve getir, varsa sadece getir.
Ayrıca servisler için bir tane Manager yazmanız lazım. Çok basit bir örnek olarak, önce bir DTO (Data Transfer Object) oluşturarak çıktıları standartlaştırın:
class ScrappedData
{
protected ?string $siteName;
protected ?string $title;
protected ?string $link;
protected ?string $image;
protected ?string $service;
public function setSiteName(?string $siteName): ScrappedData
{
$this->siteName = $siteName;
return $this;
}
public function getSiteName(): ?string
{
return $this->siteName;
}
// Diğer elemanlar için de bu şekilde getter/setter tanımladığınızı düşünün
// ...
}
Servisleriniz sonuç olarak bir ScrappedData objesi dönmesi lazım. Örneğin:
class Service1
{
public function scrap(string $url): ScrappedData
{
// Veriyi çektiniz, $data diye bir değişkene aktardınız mesela...
return (new ScrappedData)
->setSiteName($url)
->setTitle($data['title'])
->setLink($data['link'])
->setImg($data['img'])
->setService(__CLASS__)
}
}
Şimdi Manager kısmına gelelim:
class ScrapperManager
{
protected array $services;
public function __construct(array $services)
{
$this->services = $services;
}
public function scrap(): array
{
$results = [];
foreach($this->services as $service => $url) {
// Burada scrap yöntemi ScrappedData dönüyor...
$results[] = resolve($service)->scrap($url);
}
return $results;
}
}
Artık şunun gibi yapabilirsiniz:
$scrapper = new ScrapperManager([
Service1::class => 'url1',
Service2::class => 'url2',
]);
foreach($scrapper->scrap() as $data) {
// Ben burada $data'nın bir ScrappedData olduğunu biliyorum, o yüzden:
News::firstOrCreate([
'site_name' => $data->getSiteName(),
], [
'title' => $data->getTitle(),
'link' => $data->getLink(),
'img' => $data->getImg()
]);
}
Eğer servis deseni kullanmış olsaydınız kod şu kadar olacaktı:
$scrapper = new ScrapperManager([
Service1::class => 'url1',
Service2::class => 'url2',
]);
foreach($scrapper->scrap() as $scrappedData) {
$newsItem = $this->newsService->firstOrCreateFromScrappedData($scrappedData);
}