ghassan 5253f89b63 Add video platform features: authentication, video management, user profiles, likes/views tracking
- Added authentication controllers (Login, Register)
- Added UserController for user profile management
- Added VideoController with full CRUD operations
- Added Video model with relationships (user, likes, views)
- Added User model enhancements (avatar, video relationships)
- Added database migrations for video_likes, video_views, user_avatar, video_visibility
- Added CompressVideoJob for video processing
- Added VideoUploaded mail notification
- Added authentication routes
- Updated web routes with video and user routes
- Added layout templates (app, plain, partials)
- Added user views (profile, settings, channel, history, liked)
- Added video views (create, edit, index, show)
- Added email templates
2026-02-25 00:03:02 +00:00

142 lines
3.2 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
protected $fillable = [
'user_id',
'title',
'description',
'filename',
'path',
'thumbnail',
'duration',
'size',
'mime_type',
'orientation',
'width',
'height',
'status',
'visibility',
];
protected $casts = [
'duration' => 'integer',
'size' => 'integer',
'width' => 'integer',
'height' => 'integer',
];
// Relationships
public function user()
{
return $this->belongsTo(User::class);
}
public function likes()
{
return $this->belongsToMany(User::class, 'video_likes')->withTimestamps();
}
public function viewers()
{
return $this->belongsToMany(User::class, 'video_views')->withTimestamps();
}
// Accessors
public function getUrlAttribute()
{
return asset('storage/videos/' . $this->filename);
}
public function getThumbnailUrlAttribute()
{
if ($this->thumbnail) {
return asset('storage/thumbnails/' . $this->thumbnail);
}
return asset('images/video-placeholder.jpg');
}
// Check if video is liked by user
public function isLikedBy($user)
{
if (!$user) return false;
return $this->likes()->where('user_id', $user->id)->exists();
}
// Get like count
public function getLikeCountAttribute()
{
return $this->likes()->count();
}
// Get view count
public function getViewCountAttribute()
{
return $this->viewers()->count();
}
// Get shareable URL for the video
public function getShareUrlAttribute()
{
return route('videos.show', $this->id);
}
// Visibility helpers
public function isPublic()
{
return $this->visibility === 'public';
}
public function isUnlisted()
{
return $this->visibility === 'unlisted';
}
public function isPrivate()
{
return $this->visibility === 'private';
}
// Check if user can view this video
public function canView($user = null)
{
// Owner can always view
if ($user && $this->user_id === $user->id) {
return true;
}
// Public and unlisted videos can be viewed by anyone
return in_array($this->visibility, ['public', 'unlisted']);
}
// Check if video is shareable
public function isShareable()
{
// Only public and unlisted videos are shareable
return in_array($this->visibility, ['public', 'unlisted']);
}
// Scope for public videos (home page, search)
public function scopePublic($query)
{
return $query->where('visibility', 'public');
}
// Scope for videos visible to a specific user
public function scopeVisibleTo($query, $user = null)
{
if ($user) {
return $query->where(function ($q) use ($user) {
$q->where('visibility', '!=', 'private')
->orWhere('user_id', $user->id);
});
}
return $query->where('visibility', '!=', 'private');
}
}