mosamy/seenable
最新稳定版本:1.0.4
Composer 安装命令:
composer require mosamy/seenable
包简介
Track whether Eloquent records were seen and by which users.
README 文档
README
Track whether Eloquent records were seen and by which users.
Features
- Add a per-record boolean flag (
is_seen) via a global scope. - Store seen rows in
seenables(viewer + model). - Filter records by viewer (
seenBy,haventSeenBy,seenByMe,haventSeenByMe). - Mark records as seen/unseen using helper methods.
- Sort by seen/unseen priority (
orderBySeen,orderByUnseen).
Requirements
- PHP 8.1+
- Laravel 10+
Installation
composer require mosamy/seenable
Then run migrations:
php artisan migrate
Quick Start
Add the trait to any Eloquent model you want to track:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Mosamy\Seenable\Seenable;
class Message extends Model
{
use Seenable;
}
How It Works
- Each seen action creates one row in
seenablesthat links:seenable_type,seenable_id(the viewed model)seener_type,seener_id(the viewer model)
- A global scope appends
is_seento model queries.is_seen = trueif the record has at least one view by any user.
- On model delete, related view rows are deleted automatically.
API
is_seen
Check whether the record has been seen by anyone:
$message = Message::find(1);
if ($message?->is_seen) {
// Seen by at least one user
}
markAsSeen()
Mark the current authenticated user as having seen the record.
$message = Message::findOrFail(1);
$message->markAsSeen();
Notes:
- Requires an authenticated user (
auth()->user()). - Duplicate rows for the same user/record are prevented by package logic.
markAsUnseen()
Remove the seen row linked to this record.
$message = Message::findOrFail(1);
$message->markAsUnseen();
seen() relation
Get the primary seen row for the record.
$message = Message::with('seen.seener')->findOrFail(1);
$viewer = $message->seen?->seener;
views() relation
Get all views for a record.
$message = Message::with('views.seener')->findOrFail(1);
foreach ($message->views as $view) {
echo $view->seener?->id;
}
Performance tip: use eager loading (with('views.seener')) when listing many records.
seenBy(string $viewerClass, ?int $viewerId = null)
Return records seen by a specific model class, optionally a specific ID.
use App\Models\Admin;
$seenByAnyAdmin = Message::seenBy(Admin::class)->get();
$seenByAdminOne = Message::seenBy(Admin::class, 1)->get();
seenByMe()
Return records seen by the current authenticated user.
$items = Message::seenByMe()->get();
If no user is authenticated, this scope does not filter the query.
haventSeenBy(string $viewerClass, ?int $viewerId = null)
Return records not seen by a specific model class, optionally a specific ID.
use App\Models\Admin;
$notSeenByAnyAdmin = Message::haventSeenBy(Admin::class)->get();
$notSeenByAdminOne = Message::haventSeenBy(Admin::class, 1)->get();
haventSeenByMe()
Return records not seen by the current authenticated user.
$items = Message::haventSeenByMe()->get();
If no user is authenticated, this scope does not filter the query.
orderBySeen()
Sort with most-seen records first.
$items = Message::orderBySeen()->get();
orderByUnseen()
Sort with least-seen records first.
$items = Message::orderByUnseen()->get();
Caveats
is_seenreflects whether a record was seen by anyone, not by the current user.- Current implementation is centered on the
seen()relation for scopes and mark/unmark helpers, so behavior is based on the primary seen row. - If you need strict duplicate protection at DB level, add a composite unique index in your app migration strategy.
Support
For support, please contact dev.mohamed.samy@gmail.com.
Author
Created by Mohamed Samy
统计信息
- 总下载量: 16
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2023-03-21