2025-09-13 17:39:17 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
|
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
|
|
|
|
|
|
class Book extends Model
|
|
|
|
|
{
|
|
|
|
|
protected $fillable = [
|
|
|
|
|
'title',
|
|
|
|
|
'slug',
|
|
|
|
|
'author',
|
|
|
|
|
'cover_image',
|
|
|
|
|
'publication_date',
|
|
|
|
|
'description',
|
|
|
|
|
'category_id',
|
2026-03-29 15:23:02 +03:00
|
|
|
'gutenberg_id',
|
|
|
|
|
'source',
|
|
|
|
|
'full_text_url',
|
|
|
|
|
'language',
|
2025-09-13 17:39:17 +03:00
|
|
|
];
|
|
|
|
|
|
2026-03-29 15:23:02 +03:00
|
|
|
/**
|
|
|
|
|
* Get the attributes that should be cast.
|
|
|
|
|
*/
|
|
|
|
|
protected function casts(): array
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
'publication_date' => 'date',
|
|
|
|
|
'gutenberg_id' => 'integer',
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-20 16:47:41 +03:00
|
|
|
/**
|
|
|
|
|
* Use slug for route model binding and URL generation.
|
|
|
|
|
*/
|
|
|
|
|
public function getRouteKeyName(): string
|
|
|
|
|
{
|
|
|
|
|
return 'slug';
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-13 17:39:17 +03:00
|
|
|
/**
|
2026-03-29 15:23:02 +03:00
|
|
|
* Scope a query to only include books from a specific source.
|
|
|
|
|
*/
|
|
|
|
|
public function scopeFromSource($query, string $source)
|
|
|
|
|
{
|
|
|
|
|
return $query->where('source', $source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scope a query to only include manually added books.
|
|
|
|
|
*/
|
|
|
|
|
public function scopeManual($query)
|
|
|
|
|
{
|
|
|
|
|
return $query->where('source', 'manual');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scope a query to only include Gutendex imported books.
|
|
|
|
|
*/
|
|
|
|
|
public function scopeGutendex($query)
|
|
|
|
|
{
|
|
|
|
|
return $query->where('source', 'gutendex');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scope a query to only include books in a specific language.
|
|
|
|
|
*/
|
|
|
|
|
public function scopeInLanguage($query, string $language)
|
|
|
|
|
{
|
|
|
|
|
return $query->where('language', $language);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-09-13 17:39:17 +03:00
|
|
|
* Get the category that owns the book.
|
|
|
|
|
*/
|
|
|
|
|
public function category()
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsTo(Category::class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the summary associated with the book.
|
|
|
|
|
*/
|
|
|
|
|
public function summary()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasOne(Summary::class);
|
|
|
|
|
}
|
2025-09-20 16:47:41 +03:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The authors that belong to the book.
|
|
|
|
|
*/
|
|
|
|
|
public function authors()
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsToMany(Author::class, 'author_book')->withTimestamps();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Users who saved this book to their readlist.
|
|
|
|
|
*/
|
|
|
|
|
public function savedByUsers()
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsToMany(User::class, 'readlist_items')->withTimestamps();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reports submitted for this book's summary.
|
|
|
|
|
*/
|
|
|
|
|
public function reports()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(SummaryReport::class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reviews left by users for this book's summary.
|
|
|
|
|
*/
|
|
|
|
|
public function reviews()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(SummaryReview::class);
|
|
|
|
|
}
|
2025-09-13 17:39:17 +03:00
|
|
|
}
|