HasStar
The HasStar trait provides star rating functionality to Eloquent models. Add this trait to any model that can receive star ratings (products, articles, reviews, services, etc.).
Namespace
JobMetric\Star\HasStar
Overview
The HasStar trait enables models to receive star ratings from users or devices. It provides methods to add, remove, update, and query ratings. The trait uses polymorphic relationships, making it work with any Eloquent model.
Usage
Add the trait to your model:
use JobMetric\Star\HasStar;
class Product extends Model
{
use HasStar;
}
Relationships
Stars
Get all star ratings for the model:
$product->stars; // Collection of Star models
$product->stars()->where('rate', 5)->get();
Returns: MorphMany - Relationship to Star model
Available Methods
Add Star
Add or update a star rating:
$product->addStar(5, $user);
// Or with options
$product->addStar(4, $user, [
'ip' => '192.168.1.1',
'device_id' => 'abc123',
'source' => 'web',
]);
// Anonymous rating (by device)
$product->addStar(5, null, ['device_id' => 'abc123']);
Parameters:
$rate(int): The rating value (must be within min_star and max_star config)$starredBy(Model|null): The model that is rating (e.g., User). Can be null for anonymous ratings$options(array): Optional array with:ip(string|null): IP address (defaults to request IP)device_id(string|null): Device identifiersource(string|null): Source platform (e.g., 'web', 'app')
Returns: Star - The created or updated star instance
Behavior:
- If a rating already exists from the same starrer/device, it updates the rating value
- If the same rating value already exists, it returns the existing star
- Validates rating is within min_star and max_star range
- Fires
StarAddEventwhen a new rating is created
Exceptions:
MinStarException: If rating is below minimum configured valueMaxStarException: If rating is above maximum configured value
Remove Star
Remove a star rating:
$product->removeStar($user);
// Or by device
$product->removeStar(null, 'abc123');
Parameters:
$starredBy(Model|null): The starrer model (optional)$device_id(string|null): Device ID for anonymous ratings (optional)
Returns: bool - True if rating was removed
Events:
- Fires
StarRemovingEventbefore deletion - Fires
StarRemovedEventafter deletion
Has Star
Check if a star rating exists:
$product->hasStar($user);
// Or by device
$product->hasStar(null, 'abc123');
Parameters:
$starredBy(Model|null): The starrer model (optional)$device_id(string|null): Device ID (optional)
Returns: bool - True if rating exists
Star Count
Get total count of all star ratings:
$product->starCount();
Returns: int - Total rating count
Star Average
Get average of all star ratings:
$product->starAvg();
// Returns: 4.3 (float)
Returns: float - Average rating value
Star Summary
Get a summary of all rating values with counts:
$summary = $product->starSummary();
// Returns: [5 => 10, 4 => 5, 3 => 2, 2 => 1, 1 => 0]
Returns: Collection<int, int> - Map of rating value => count
Latest Stars
Get the latest star ratings:
$stars = $product->latestStars(10);
Parameters:
$limit(int): Number of ratings to retrieve (default: 5)
Returns: EloquentCollection<Star> - Collection of Star models
Forget Stars
Remove all star ratings by a starrer or device:
$product->forgetStars($user);
// Or by device
$product->forgetStars(null, 'abc123');
Parameters:
$starredBy(Model|null): The starrer model (optional)$device_id(string|null): Device ID (optional)
Returns: int - Number of ratings removed
Is Rated As
Check if rated with a specific value:
$product->isRatedAs(5, $user);
// Or by device
$product->isRatedAs(4, null, 'abc123');
Parameters:
$rate(int): The rating value to check$starredBy(Model|null): The starrer model (optional)$device_id(string|null): Device ID (optional)
Returns: bool - True if rated with the specified value
Get Rated Value
Get the rating value given by a starrer or device:
$rate = $product->getRatedValue($user);
// Returns: 5 or null
// Or by device
$rate = $product->getRatedValue(null, 'abc123');
Parameters:
$starredBy(Model|null): The starrer model (optional)$device_id(string|null): Device ID (optional)
Returns: int|null - The rating value or null
Is Rated Above
Check if rating is above a certain value:
$product->isRatedAbove(3, $user);
Parameters:
$value(int): The value to compare against$starredBy(Model|null): The starrer model (optional)$device_id(string|null): Device ID (optional)
Returns: bool - True if rating is above the value
Is Rated Below
Check if rating is below a certain value:
$product->isRatedBelow(5, $user);
Parameters:
$value(int): The value to compare against$starredBy(Model|null): The starrer model (optional)$device_id(string|null): Device ID (optional)
Returns: bool - True if rating is below the value
Complete Examples
Basic Usage
use JobMetric\Star\HasStar;
class Product extends Model
{
use HasStar;
}
$product = Product::find(1);
$user = User::find(1);
// Add 5-star rating
$product->addStar(5, $user);
// Check if rated
if ($product->hasStar($user)) {
echo "User rated this product";
}
// Get average rating
$average = $product->starAvg();
// Get rating count
$count = $product->starCount();
// Get user's rating
$userRating = $product->getRatedValue($user);
// Remove rating
$product->removeStar($user);
Rating Summary
$product = Product::find(1);
// Get summary of all ratings
$summary = $product->starSummary();
// Returns: [5 => 50, 4 => 30, 3 => 15, 2 => 4, 1 => 1]
// Display in view
foreach ($summary as $rate => $count) {
echo "{$rate} stars: {$count} ratings\n";
}
// Calculate percentage
$total = $product->starCount();
foreach ($summary as $rate => $count) {
$percentage = ($count / $total) * 100;
echo "{$rate} stars: {$percentage}%\n";
}
Latest Ratings
$product = Product::find(1);
// Get latest 10 ratings
$latest = $product->latestStars(10);
foreach ($latest as $star) {
echo "{$star->starredBy->name} rated {$star->rate} stars\n";
}
Anonymous Ratings
// Add rating by device (anonymous user)
$product->addStar(5, null, ['device_id' => 'device-123']);
// Check anonymous rating
$hasRating = $product->hasStar(null, 'device-123');
// Get anonymous rating value
$rating = $product->getRatedValue(null, 'device-123');
// Remove anonymous rating
$product->removeStar(null, 'device-123');
Conditional Checks
$product = Product::find(1);
$user = User::find(1);
// Check specific rating
if ($product->isRatedAs(5, $user)) {
echo "User gave 5 stars";
}
// Check if rated above 3
if ($product->isRatedAbove(3, $user)) {
echo "User rated above 3 stars";
}
// Check if rated below 5
if ($product->isRatedBelow(5, $user)) {
echo "User rated below 5 stars";
}
When to Use HasStar
Use the HasStar trait when you need to:
- Product Ratings: Add star ratings to products in e-commerce
- Content Ratings: Rate articles, posts, reviews, etc.
- Service Ratings: Rate services, restaurants, hotels
- Quality Assessment: Track quality ratings for any content
- Analytics: Collect rating data for analytics and insights
- Anonymous Ratings: Support ratings from non-authenticated users
- Flexible Rating Scales: Use any rating scale (1-5, 0-10, etc.)