vsmov 1.0.0

This commit is contained in:
Clemencia John
2026-04-15 21:11:19 -07:00
parent 311c74228c
commit 68260d170a
147 changed files with 12113 additions and 0 deletions

191
src/Models/Actor.php Normal file
View File

@@ -0,0 +1,191 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Backpack\Settings\app\Models\Setting;
use Vsmov\Core\Contracts\TaxonomyInterface;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Vsmov\Core\Contracts\SeoInterface;
use Vsmov\Core\Traits\HasFactory;
use Vsmov\Core\Traits\HasTitle;
use Vsmov\Core\Traits\HasDescription;
use Vsmov\Core\Traits\HasKeywords;
use Vsmov\Core\Traits\HasUniqueName;
use Vsmov\Core\Traits\Sluggable;
use Illuminate\Support\Str;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\TwitterCard;
class Actor extends Model implements TaxonomyInterface, Cacheable, SeoInterface
{
use CrudTrait;
use Sluggable;
use HasUniqueName;
use HasFactory;
use HasCache;
use HasTitle;
use HasDescription;
use HasKeywords;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'actors';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public static function primaryCacheKey(): string
{
$site_routes = setting('site_routes_actors', '/dien-vien/{actor}');
if (strpos($site_routes, '{actor}')) return 'slug';
if (strpos($site_routes, '{id}')) return 'id';
return 'slug';
}
public function getUrl()
{
$params = [];
$site_routes = setting('site_routes_actors', '/dien-vien/{actor}');
if (strpos($site_routes, '{actor}')) $params['actor'] = $this->slug;
if (strpos($site_routes, '{id}')) $params['id'] = $this->id;
return route('actors.movies.index', $params);
}
protected function titlePattern(): string
{
return Setting::get('site_actor_title', '');
}
protected function descriptionPattern(): string
{
return Setting::get('site_actor_des', '');
}
protected function keywordsPattern(): string
{
return Setting::get('site_actor_key', '');
}
public function generateSeoTags()
{
$seo_title = $this->getTitle();
$seo_des = Str::limit($this->getDescription(), 150, '...');
$seo_key = $this->getKeywords();
$movie_thumb_url = '';
$movie_poster_url = '';
$updated_at = '';
if(count($this->movies)) {
$movie_thumb_url = filter_var($this->movies->last()->thumb_url, FILTER_VALIDATE_URL) ? $this->movies->last()->thumb_url : request()->root() . $this->movies->last()->thumb_url;
$movie_poster_url = filter_var($this->movies->last()->poster_url, FILTER_VALIDATE_URL) ? $this->movies->last()->poster_url : request()->root() . $this->movies->last()->poster_url;
$updated_at = $this->movies->last()->updated_at;
}
$getUrl = $this->getUrl();
$site_meta_siteName = setting('site_meta_siteName');
SEOMeta::setTitle($seo_title, false)
->setDescription($seo_des)
->addKeyword([$seo_key])
->setCanonical($getUrl)
->setPrev(request()->root())
->setPrev(request()->root());
OpenGraph::setSiteName($site_meta_siteName)
->setType('website')
->setTitle($seo_title, false)
->addProperty('locale', 'vi-VN')
->addProperty('updated_time', $updated_at)
->addProperty('url', $getUrl)
->setDescription($seo_des)
->addImages([$movie_thumb_url, $movie_poster_url]);
TwitterCard::setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('summary')
->setImage($movie_thumb_url)
->setDescription($seo_des)
->setUrl($getUrl);
JsonLdMulti::newJsonLd()
->setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('WebPage')
->addValue('dateCreated', $updated_at)
->addValue('dateModified', $updated_at)
->addValue('datePublished', $updated_at)
->setDescription($seo_des)
->setImages([$movie_thumb_url, $movie_poster_url])
->setUrl($getUrl);
$breadcrumb = [];
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 1,
'name' => 'Home',
'item' => url('/')
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $this->name,
'item' => $getUrl
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 3,
'name' => "Trang " . (request()->get('page') ?: 1),
]);
JsonLdMulti::newJsonLd()
->setType('BreadcrumbList')
->addValue('name', '')
->addValue('description', '')
->addValue('itemListElement', $breadcrumb);
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function movies()
{
return $this->belongsToMany(Movie::class);
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
}

153
src/Models/Catalog.php Normal file
View File

@@ -0,0 +1,153 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Backpack\Settings\app\Models\Setting;
use Vsmov\Core\Contracts\TaxonomyInterface;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Vsmov\Core\Contracts\SeoInterface;
use Vsmov\Core\Traits\HasFactory;
use Vsmov\Core\Traits\Sluggable;
use Illuminate\Support\Str;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\TwitterCard;
class Catalog extends Model implements TaxonomyInterface, Cacheable, SeoInterface
{
use CrudTrait;
use Sluggable;
use HasFactory;
use HasCache;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'catalogs';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public static function primaryCacheKey(): string
{
$site_routes = setting('site_routes_types', '/danh-sach/{type}');
if (strpos($site_routes, '{type}')) return 'slug';
if (strpos($site_routes, '{id}')) return 'id';
return 'slug';
}
public function getUrl()
{
$params = [];
$site_routes = setting('site_routes_types', '/danh-sach/{type}');
if (strpos($site_routes, '{type}')) $params['type'] = $this->slug;
if (strpos($site_routes, '{id}')) $params['id'] = $this->id;
return route('types.movies.index', $params);
}
public function generateSeoTags()
{
$seo_title = $this->seo_title;
$seo_des = $this->seo_des;
$seo_key = $this->seo_key;
$getUrl = $this->getUrl();
$site_meta_siteName = setting('site_meta_siteName');
SEOMeta::setTitle($seo_title, false)
->setDescription($seo_des)
->addKeyword([$seo_key])
->setCanonical($getUrl)
->setPrev(request()->root())
->setPrev(request()->root());
OpenGraph::setSiteName($site_meta_siteName)
->setType('website')
->setTitle($seo_title, false)
->addProperty('locale', 'vi-VN')
->addProperty('url', $getUrl)
->setDescription($seo_des);
TwitterCard::setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('summary')
->setDescription($seo_des)
->setUrl($getUrl);
JsonLdMulti::newJsonLd()
->setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('WebPage')
->setDescription($seo_des)
->setUrl($getUrl);
$breadcrumb = [];
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 1,
'name' => 'Home',
'item' => url('/')
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $this->name,
'item' => $getUrl
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 3,
'name' => "Trang " . (request()->get('page') ?: 1),
]);
JsonLdMulti::newJsonLd()
->setType('BreadcrumbList')
->addValue('name', '')
->addValue('description', '')
->addValue('itemListElement', $breadcrumb);
}
public function openView($crud = false)
{
return '<a class="btn btn-sm btn-link" target="_blank" href="'.$this->getUrl().'" data-toggle="tooltip" title="View link"><i class="la la-link"></i> View</a>';
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
}

192
src/Models/Category.php Normal file
View File

@@ -0,0 +1,192 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Backpack\Settings\app\Models\Setting;
use Vsmov\Core\Contracts\TaxonomyInterface;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Vsmov\Core\Contracts\SeoInterface;
use Vsmov\Core\Traits\ActorLog;
use Vsmov\Core\Traits\HasFactory;
use Vsmov\Core\Traits\HasTitle;
use Vsmov\Core\Traits\HasDescription;
use Vsmov\Core\Traits\HasKeywords;
use Vsmov\Core\Traits\Sluggable;
use Illuminate\Support\Str;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\TwitterCard;
class Category extends Model implements TaxonomyInterface, Cacheable, SeoInterface
{
use CrudTrait;
use ActorLog;
use Sluggable;
use HasFactory;
use HasCache;
use HasTitle;
use HasDescription;
use HasKeywords;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'categories';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public static function primaryCacheKey(): string
{
$site_routes = setting('site_routes_category', '/the-loai/{category}');
if (strpos($site_routes, '{category}')) return 'slug';
if (strpos($site_routes, '{id}')) return 'id';
return 'slug';
}
public function getUrl($withDomain = true)
{
$params = [];
$site_routes = setting('site_routes_category', '/the-loai/{category}');
if (strpos($site_routes, '{category}')) $params['category'] = $this->slug;
if (strpos($site_routes, '{id}')) $params['id'] = $this->id;
return route('categories.movies.index', $params, $withDomain);
}
protected function titlePattern(): string
{
return Setting::get('site_category_title', '');
}
protected function descriptionPattern(): string
{
return Setting::get('site_category_des', '');
}
protected function keywordsPattern(): string
{
return Setting::get('site_category_key', '');
}
public function generateSeoTags()
{
$seo_title = $this->seo_title ?: $this->getTitle();
$seo_des = Str::limit($this->seo_des ?: $this->getDescription(), 150, '...');
$seo_key = $this->seo_key ?: $this->getKeywords();
$movie_thumb_url = '';
$movie_poster_url = '';
$updated_at = '';
if(count($this->movies)) {
$movie_thumb_url = filter_var($this->movies->last()->thumb_url, FILTER_VALIDATE_URL) ? $this->movies->last()->thumb_url : request()->root() . $this->movies->last()->thumb_url;
$movie_poster_url = filter_var($this->movies->last()->poster_url, FILTER_VALIDATE_URL) ? $this->movies->last()->poster_url : request()->root() . $this->movies->last()->poster_url;
$updated_at = $this->movies->last()->updated_at;
}
$getUrl = $this->getUrl();
$site_meta_siteName = setting('site_meta_siteName');
SEOMeta::setTitle($seo_title, false)
->setDescription($seo_des)
->addKeyword([$seo_key])
->setCanonical($getUrl)
->setPrev(request()->root())
->setPrev(request()->root());
OpenGraph::setSiteName($site_meta_siteName)
->setType('website')
->setTitle($seo_title, false)
->addProperty('locale', 'vi-VN')
->addProperty('updated_time', $updated_at)
->addProperty('url', $getUrl)
->setDescription($seo_des)
->addImages([$movie_thumb_url,$movie_poster_url]);
TwitterCard::setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('summary')
->setImage($movie_thumb_url)
->setDescription($seo_des)
->setUrl($getUrl);
JsonLdMulti::newJsonLd()
->setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('WebPage')
->addValue('dateCreated', $updated_at)
->addValue('dateModified', $updated_at)
->addValue('datePublished', $updated_at)
->setDescription($seo_des)
->setImages([$movie_thumb_url,$movie_poster_url])
->setUrl($getUrl);
$breadcrumb = [];
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 1,
'name' => 'Home',
'item' => url('/')
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $this->name,
'item' => $getUrl
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 3,
'name' => "Trang " . (request()->get('page') ?: 1),
]);
JsonLdMulti::newJsonLd()
->setType('BreadcrumbList')
->addValue('name', '')
->addValue('description', '')
->addValue('itemListElement', $breadcrumb);
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function movies()
{
return $this->belongsToMany(Movie::class);
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
}

192
src/Models/Director.php Normal file
View File

@@ -0,0 +1,192 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Backpack\Settings\app\Models\Setting;
use Vsmov\Core\Contracts\TaxonomyInterface;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Vsmov\Core\Contracts\SeoInterface;
use Vsmov\Core\Traits\HasFactory;
use Vsmov\Core\Traits\HasTitle;
use Vsmov\Core\Traits\HasDescription;
use Vsmov\Core\Traits\HasKeywords;
use Vsmov\Core\Traits\HasUniqueName;
use Vsmov\Core\Traits\Sluggable;
use Illuminate\Support\Str;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\TwitterCard;
class Director extends Model implements TaxonomyInterface, Cacheable, SeoInterface
{
use CrudTrait;
use Sluggable;
use HasUniqueName;
use HasFactory;
use HasCache;
use HasTitle;
use HasDescription;
use HasKeywords;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'directors';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public static function primaryCacheKey(): string
{
$site_routes = setting('site_routes_directors', '/dien-vien/{director}');
if (strpos($site_routes, '{director}')) return 'slug';
if (strpos($site_routes, '{id}')) return 'id';
return 'slug';
}
public function getUrl()
{
$params = [];
$site_routes = setting('site_routes_directors', '/dien-vien/{director}');
if (strpos($site_routes, '{director}')) $params['director'] = $this->slug;
if (strpos($site_routes, '{id}')) $params['id'] = $this->id;
return route('directors.movies.index', $params);
}
protected function titlePattern(): string
{
return Setting::get('site_director_title', '');
}
protected function descriptionPattern(): string
{
return Setting::get('site_director_des', '');
}
protected function keywordsPattern(): string
{
return Setting::get('site_director_key', '');
}
public function generateSeoTags()
{
$seo_title = $this->getTitle();
$seo_des = Str::limit($this->getDescription(), 150, '...');
$seo_key = $this->getKeywords();
$movie_thumb_url = '';
$movie_poster_url = '';
$updated_at = '';
if(count($this->movies)) {
$movie_thumb_url = filter_var($this->movies->last()->thumb_url, FILTER_VALIDATE_URL) ? $this->movies->last()->thumb_url : request()->root() . $this->movies->last()->thumb_url;
$movie_poster_url = filter_var($this->movies->last()->poster_url, FILTER_VALIDATE_URL) ? $this->movies->last()->poster_url : request()->root() . $this->movies->last()->poster_url;
$updated_at = $this->movies->last()->updated_at;
}
$getUrl = $this->getUrl();
$site_meta_siteName = setting('site_meta_siteName');
SEOMeta::setTitle($seo_title, false)
->setDescription($seo_des)
->addKeyword([$seo_key])
->setCanonical($getUrl)
->setPrev(request()->root())
->setPrev(request()->root());
OpenGraph::setSiteName($site_meta_siteName)
->setType('website')
->setTitle($seo_title, false)
->addProperty('locale', 'vi-VN')
->addProperty('updated_time', $updated_at)
->addProperty('url', $getUrl)
->setDescription($seo_des)
->addImages([$movie_thumb_url, $movie_poster_url]);
TwitterCard::setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('summary')
->setImage($movie_thumb_url)
->setDescription($seo_des)
->setUrl($getUrl);
JsonLdMulti::newJsonLd()
->setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('WebPage')
->addValue('dateCreated', $updated_at)
->addValue('dateModified', $updated_at)
->addValue('datePublished', $updated_at)
->setDescription($seo_des)
->setImages([$movie_thumb_url, $movie_poster_url])
->setUrl($getUrl);
$breadcrumb = [];
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 1,
'name' => 'Home',
'item' => url('/')
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $this->name,
'item' => $getUrl
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 3,
'name' => "Trang " . (request()->get('page') ?: 1),
]);
JsonLdMulti::newJsonLd()
->setType('BreadcrumbList')
->addValue('name', '')
->addValue('description', '')
->addValue('itemListElement', $breadcrumb);
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function movies()
{
return $this->belongsToMany(Movie::class);
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
}

212
src/Models/Episode.php Normal file
View File

@@ -0,0 +1,212 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Backpack\Settings\app\Models\Setting;
use Vsmov\Core\Contracts\HasUrlInterface;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Vsmov\Core\Contracts\SeoInterface;
use Vsmov\Core\Traits\HasFactory;
use Vsmov\Core\Traits\HasTitle;
use Illuminate\Support\Str;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\TwitterCard;
class Episode extends Model implements Cacheable, HasUrlInterface, SeoInterface
{
use CrudTrait;
use HasFactory;
use HasCache;
use HasTitle;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'episodes';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public function getUrl()
{
$movie = Cache::remember("cache_movie_by_id:" . $this->movie_id, setting('site_cache_ttl', 5 * 60), function () {
return $this->movie;
});
$params = [];
$site_routes_movie = setting('site_routes_episode', '/phim/{movie}/{episode}-{id}');
if (strpos($site_routes_movie, '{movie}')) $params['movie'] = $movie->slug;
if (strpos($site_routes_movie, '{movie_id}')) $params['movie_id'] = $movie->id;
if (strpos($site_routes_movie, '{episode}')) $params['episode'] = $this->slug;
if (strpos($site_routes_movie, '{id}')) $params['id'] = $this->id;
return route('episodes.show', $params);
}
public function openEpisode($crud = false)
{
return '<a class="btn btn-sm btn-link" target="_blank" href="' . $this->getUrl() . '" data-toggle="tooltip" title="Just a demo custom button."><i class="fa fa-search"></i> Open it</a>';
}
protected function titlePattern(): string
{
return Setting::get('site_episode_watch_title', '');
}
public function generateSeoTags()
{
$movie_thumb_url = filter_var($this->movie->thumb_url, FILTER_VALIDATE_URL) ? $this->movie->thumb_url : request()->root() . $this->movie->thumb_url;
$movie_poster_url = filter_var($this->movie->poster_url, FILTER_VALIDATE_URL) ? $this->movie->poster_url : request()->root() . $this->movie->poster_url;
$movie_description = Str::limit(strip_tags($this->movie->content), 150, '...');
$episode_getUrl = $this->getUrl();
$getTitle = $this->getTitle();
$site_meta_siteName = setting('site_meta_siteName');
SEOMeta::setTitle($getTitle, false)
->setDescription($movie_description)
->addKeyword($this->movie->tags()->pluck('name')->toArray())
->addMeta('article:published_time', $this->updated_at->toW3CString(), 'property')
->addMeta('article:section', $this->movie->categories->pluck('name')->join(","), 'property')
->addMeta('article:tag', $this->movie->tags->pluck('name')->join(","), 'property')
->setCanonical($episode_getUrl)
->setPrev(request()->root())
->setPrev(request()->root());
OpenGraph::setType('video.episode')
->setSiteName($site_meta_siteName)
->setTitle($getTitle, false)
->addProperty('locale', 'vi-VN')
->addProperty('url', $episode_getUrl)
->addProperty('updated_time', $this->movie->updated_at)
->setDescription($movie_description)
->addImages([$movie_thumb_url,$movie_poster_url])
->setVideoEpisode([
'actor' => $this->movie->actors->pluck('name')->join(","),
'director' => $this->movie->directors->pluck('name')->join(","),
'duration' => $this->movie->episode_time,
'release_date' => $this->created_at,
'tag' => $this->movie->tags->pluck('name')->join(", "),
'series' => 'video.tv_show'
]);
TwitterCard::setSite($site_meta_siteName)
->setTitle($getTitle, false)
->setType('summary')
->setImage($movie_thumb_url)
->setDescription($movie_description)
->setUrl($episode_getUrl);
JsonLdMulti::newJsonLd()
->setSite($site_meta_siteName)
->addValue('dateCreated', $this->created_at)
->addValue('dateModified', $this->updated_at)
->addValue('datePublished', $this->created_at)
->setTitle($getTitle, false)
->setType('Movie')
->setDescription($movie_description)
->setImages([$movie_thumb_url,$movie_poster_url])
->addValue('aggregateRating', [
'@type' => 'AggregateRating',
'bestRating' => "10",
'worstRating' => "1",
'ratingValue' => $this->movie->getRatingStar(),
'reviewCount' => $this->movie->getRatingCount()
])
->addValue('director', count($this->movie->directors) ? $this->movie->directors->map(function ($director) {
return ['@type'=> 'Person', 'name' => $director->name];
}) : "")
->addValue('actor', count($this->movie->actors) ? $this->movie->actors->map(function ($actor) {
return ['@type'=> 'Person', 'name' => $actor->name];
}) : "")
->setUrl($episode_getUrl);
// ->addValue($key, $value);
$breadcrumb = [];
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 1,
'name' => 'Home',
'item' => url('/')
]);
foreach ($this->movie->regions as $item) {
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $item->name,
'item' => $item->getUrl(),
]);
}
foreach ($this->movie->categories as $item) {
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $item->name,
'item' => $item->getUrl(),
]);
}
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 3,
'name' => $this->movie->name,
'item' => $this->movie->getUrl()
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 4,
'name' => "Tập " . $this->name,
]);
JsonLdMulti::newJsonLd()
->setType('BreadcrumbList')
->addValue('name', '')
->addValue('description', '')
->addValue('itemListElement', $breadcrumb);
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function movie()
{
return $this->belongsTo(Movie::class);
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
}

76
src/Models/Menu.php Normal file
View File

@@ -0,0 +1,76 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Vsmov\Core\Traits\HasFactory;
class Menu extends Model implements Cacheable
{
use CrudTrait;
use HasFactory;
use HasCache;
protected $table = 'menus';
protected $fillable = ['name', 'type', 'link', 'parent_id', 'lft', 'rgt'];
public function parent()
{
return $this->belongsTo(static::class, 'parent_id');
}
public function children()
{
return $this->hasMany(static::class, 'parent_id');
}
/**
* Get all menu items, in a hierarchical collection.
* Only supports 2 levels of indentation.
*/
public static function getTree()
{
$menu = self::fromCache()->all()->sortBy('lft');
if ($menu->count()) {
foreach ($menu as $k => $menu_item) {
$menu_item->children = collect([]);
foreach ($menu as $i => $menu_subitem) {
if ($menu_subitem->parent_id == $menu_item->id) {
$menu_item->children->push($menu_subitem);
// remove the subitem for the first level
$menu = $menu->reject(function ($item) use ($menu_subitem) {
return $item->id == $menu_subitem->id;
});
}
}
}
}
return $menu;
}
public function url()
{
switch ($this->type) {
case 'external_link':
return $this->link;
break;
case 'internal_link':
return is_null($this->link) ? '#' : url($this->link);
break;
default: //page_link
if ($this->page) {
return url($this->page->slug);
}
break;
}
}
}

308
src/Models/Movie.php Normal file
View File

@@ -0,0 +1,308 @@
<?php
namespace Vsmov\Core\Models;
use Illuminate\Support\Str;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\TwitterCard;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Backpack\Settings\app\Models\Setting;
use Vsmov\Core\Contracts\TaxonomyInterface;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Vsmov\Core\Contracts\SeoInterface;
use Vsmov\Core\Traits\ActorLog;
use Vsmov\Core\Traits\HasFactory;
use Vsmov\Core\Traits\HasTitle;
use Vsmov\Core\Traits\Sluggable;
class Movie extends Model implements TaxonomyInterface, Cacheable, SeoInterface
{
use CrudTrait;
use ActorLog;
use Sluggable;
use HasFactory;
use HasCache;
use HasTitle;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'movies';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public static function boot()
{
parent::boot();
static::updating(function ($instance) {
$instance->timestamps = request('timestamps') ?: false;
});
}
public static function primaryCacheKey(): string
{
$site_routes = setting('site_routes_movie', '/phim/{movie}');
if (strpos($site_routes, '{movie}')) return 'slug';
if (strpos($site_routes, '{id}')) return 'id';
return 'slug';
}
public function getUrl()
{
$params = [];
$site_routes = setting('site_routes_movie', '/phim/{movie}');
if (strpos($site_routes, '{movie}')) $params['movie'] = $this->slug;
if (strpos($site_routes, '{id}')) $params['id'] = $this->id;
return route('movies.show', $params);
}
public function getThumbUrl()
{
if (setting('site_image_proxy_enable', false)) {
$image_url = filter_var($this->thumb_url, FILTER_VALIDATE_URL) ? $this->thumb_url : url('/') . $this->thumb_url;
return str_replace('{image_url}', urlencode($image_url), setting('site_image_proxy_url', ''));
}
return $this->thumb_url;
}
public function getPosterUrl()
{
if ($this->poster_url) {
if (setting('site_image_proxy_enable', false)) {
$image_url = filter_var($this->poster_url, FILTER_VALIDATE_URL) ? $this->poster_url : url('/') . $this->poster_url;
return str_replace('{image_url}', urlencode($image_url), setting('site_image_proxy_url', ''));
}
return $this->poster_url;
}
return $this->getThumbUrl();
}
public function getRatingStar()
{
return number_format($this->rating_star > 0 ? $this->rating_star : 8, 1);
}
public function getRatingCount()
{
return $this->rating_count >= 1 ? $this->rating_count : 1;
}
public function generateSeoTags()
{
$movie_thumb_url = filter_var($this->thumb_url, FILTER_VALIDATE_URL) ? $this->thumb_url : request()->root() . $this->thumb_url;
$movie_poster_url = filter_var($this->poster_url, FILTER_VALIDATE_URL) ? $this->poster_url : request()->root() . $this->poster_url;
$seo_des = Str::limit(strip_tags($this->content), 150, '...');
$getTitle = $this->getTitle();
$getUrl = $this->getUrl();
$site_meta_siteName = setting('site_meta_siteName');
SEOMeta::setTitle($getTitle, false)
->setDescription($seo_des)
->addKeyword($this->tags()->pluck('name')->toArray())
->addMeta('article:published_time', $this->updated_at->toW3CString(), 'property')
->addMeta('article:section', $this->categories->pluck('name')->join(","), 'property')
->addMeta('article:tag', $this->tags->pluck('name')->join(","), 'property')
->setCanonical($getUrl)
->setPrev(url('/'))
->setPrev(url('/'));
if ($this->type === 'single') {
OpenGraph::setType('video.movie')
->setTitle($getTitle, false)
->setDescription($seo_des)
->setSiteName($site_meta_siteName)
->addProperty('locale', 'vi-VN')
->addProperty('updated_time', $this->updated_at)
->addProperty('url', $getUrl)
->addImages([$movie_thumb_url,$movie_poster_url])
->setVideoMovie([
'actor' => $this->actors->pluck('name')->join(","),
'director' => $this->directors->pluck('name')->join(","),
'duration' => $this->episode_time,
'release_date' => $this->created_at,
'tag' => $this->tags->pluck('name')->join(", ")
]);
} else {
OpenGraph::setType('video.tv_show')
->setTitle($getTitle, false)
->setDescription($seo_des)
->setSiteName($site_meta_siteName)
->addProperty('locale', 'vi-VN')
->addProperty('updated_time', $this->updated_at)
->addProperty('url', $getUrl)
->addImages([$movie_thumb_url,$movie_poster_url])
->setVideoTVShow([
'actor' => $this->actors->pluck('name')->join(","),
'director' => $this->directors->pluck('name')->join(","),
'duration' => $this->episode_time,
'release_date' => $this->created_at,
'tag' => $this->tags->pluck('name')->join(", ")
]);
}
TwitterCard::setSite($site_meta_siteName)
->setTitle($getTitle, false)
->setType('summary')
->setImage($movie_thumb_url)
->setDescription($seo_des)
->setUrl($getUrl);
JsonLdMulti::newJsonLd()
->setSite($site_meta_siteName)
->addValue('dateCreated', $this->created_at)
->addValue('dateModified', $this->updated_at)
->addValue('datePublished', $this->created_at)
->setTitle($getTitle, false)
->setType('Movie')
->setDescription($seo_des)
->setImages([$movie_thumb_url, $movie_poster_url])
->addValue('aggregateRating', [
'@type' => 'AggregateRating',
'bestRating' => "10",
'worstRating' => "1",
'ratingValue' => $this->getRatingStar(),
'reviewCount' => $this->getRatingCount()
])
->addValue('director', count($this->directors) ? $this->directors->map(function ($director) {
return ['@type' => 'Person', 'name' => $director->name];
}) : "")
->addValue('actor', count($this->actors) ? $this->actors->map(function ($actor) {
return ['@type' => 'Person', 'name' => $actor->name];
}) : "")
->setUrl($getUrl);
$breadcrumb = [];
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 1,
'name' => 'Home',
'item' => url('/')
]);
foreach ($this->regions as $item) {
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $item->name,
'item' => $item->getUrl(),
]);
}
foreach ($this->categories as $item) {
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $item->name,
'item' => $item->getUrl(),
]);
}
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 3,
'name' => $this->name
]);
JsonLdMulti::newJsonLd()
->setType('BreadcrumbList')
->addValue('name', '')
->addValue('description', '')
->addValue('itemListElement', $breadcrumb);
}
public function openView($crud = false)
{
return '<a class="btn btn-sm btn-link" target="_blank" href="' . $this->getUrl() . '" data-toggle="tooltip" title="View link"><i class="la la-link"></i> View</a>';
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function categories()
{
return $this->belongsToMany(Category::class);
}
public function regions()
{
return $this->belongsToMany(Region::class);
}
public function directors()
{
return $this->belongsToMany(Director::class);
}
public function actors()
{
return $this->belongsToMany(Actor::class);
}
public function tags()
{
return $this->belongsToMany(Tag::class);
}
public function episodes()
{
return $this->hasMany(Episode::class);
}
public function studios()
{
return $this->belongsToMany(Studio::class);
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
public function getStatus()
{
$statuses = [
'trailer' => __('Sắp chiếu'),
'ongoing' => __('Đang chiếu'),
'completed' => __('Hoàn thành')
];
return $statuses[$this->status];
}
protected function titlePattern(): string
{
return Setting::get('site_movie_title', '');
}
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
}

192
src/Models/Region.php Normal file
View File

@@ -0,0 +1,192 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Backpack\Settings\app\Models\Setting;
use Vsmov\Core\Contracts\TaxonomyInterface;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Vsmov\Core\Contracts\SeoInterface;
use Vsmov\Core\Traits\ActorLog;
use Vsmov\Core\Traits\HasFactory;
use Vsmov\Core\Traits\HasTitle;
use Vsmov\Core\Traits\HasDescription;
use Vsmov\Core\Traits\HasKeywords;
use Vsmov\Core\Traits\Sluggable;
use Illuminate\Support\Str;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\TwitterCard;
class Region extends Model implements TaxonomyInterface, Cacheable, SeoInterface
{
use CrudTrait;
use ActorLog;
use Sluggable;
use HasFactory;
use HasCache;
use HasTitle;
use HasDescription;
use HasKeywords;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'regions';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public static function primaryCacheKey(): string
{
$site_routes = setting('site_routes_region', '/quoc-gia/{region}');
if (strpos($site_routes, '{region}')) return 'slug';
if (strpos($site_routes, '{id}')) return 'id';
return 'slug';
}
public function getUrl($withDomain = true)
{
$params = [];
$site_routes = setting('site_routes_region', '/quoc-gia/{region}');
if (strpos($site_routes, '{region}')) $params['region'] = $this->slug;
if (strpos($site_routes, '{id}')) $params['id'] = $this->id;
return route('regions.movies.index', $params, $withDomain);
}
protected function titlePattern(): string
{
return Setting::get('site_region_title', '');
}
protected function descriptionPattern(): string
{
return Setting::get('site_region_des', '');
}
protected function keywordsPattern(): string
{
return Setting::get('site_region_key', '');
}
public function generateSeoTags()
{
$seo_title = $this->seo_title ?: $this->getTitle();
$seo_des = Str::limit($this->seo_des ?: $this->getDescription(), 150, '...');
$seo_key = $this->seo_key ?: $this->getKeywords();
$movie_thumb_url = '';
$movie_poster_url = '';
$updated_at = '';
if(count($this->movies)) {
$movie_thumb_url = filter_var($this->movies->last()->thumb_url, FILTER_VALIDATE_URL) ? $this->movies->last()->thumb_url : request()->root() . $this->movies->last()->thumb_url;
$movie_poster_url = filter_var($this->movies->last()->poster_url, FILTER_VALIDATE_URL) ? $this->movies->last()->poster_url : request()->root() . $this->movies->last()->poster_url;
$updated_at = $this->movies->last()->updated_at;
}
$getUrl = $this->getUrl();
$site_meta_siteName = setting('site_meta_siteName');
SEOMeta::setTitle($seo_title, false)
->setDescription($seo_des)
->addKeyword([$seo_key])
->setCanonical($getUrl)
->setPrev(request()->root())
->setPrev(request()->root());
OpenGraph::setSiteName($site_meta_siteName)
->setType('website')
->setTitle($seo_title, false)
->addProperty('locale', 'vi-VN')
->addProperty('updated_time', $updated_at)
->addProperty('url', $getUrl)
->setDescription($seo_des)
->addImages([$movie_thumb_url, $movie_poster_url]);
TwitterCard::setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('summary')
->setImage($movie_thumb_url)
->setDescription($seo_des)
->setUrl($getUrl);
JsonLdMulti::newJsonLd()
->setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('WebPage')
->addValue('dateCreated', $updated_at)
->addValue('dateModified', $updated_at)
->addValue('datePublished', $updated_at)
->setDescription($seo_des)
->setImages([$movie_thumb_url, $movie_poster_url])
->setUrl($getUrl);
$breadcrumb = [];
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 1,
'name' => 'Home',
'item' => url('/')
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $this->name,
'item' => $getUrl
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 3,
'name' => "Trang " . (request()->get('page') ?: 1),
]);
JsonLdMulti::newJsonLd()
->setType('BreadcrumbList')
->addValue('name', '')
->addValue('description', '')
->addValue('itemListElement', $breadcrumb);
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function movies()
{
return $this->belongsToMany(Movie::class);
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
}

149
src/Models/Studio.php Normal file
View File

@@ -0,0 +1,149 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Backpack\Settings\app\Models\Setting;
use Vsmov\Core\Contracts\TaxonomyInterface;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Vsmov\Core\Contracts\SeoInterface;
use Vsmov\Core\Traits\HasFactory;
use Vsmov\Core\Traits\HasTitle;
use Vsmov\Core\Traits\HasDescription;
use Vsmov\Core\Traits\HasKeywords;
use Vsmov\Core\Traits\HasUniqueName;
use Vsmov\Core\Traits\Sluggable;
use Illuminate\Support\Str;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\TwitterCard;
class Studio extends Model implements TaxonomyInterface, Cacheable, SeoInterface
{
use CrudTrait;
use Sluggable;
use HasUniqueName;
use HasFactory;
use HasCache;
use HasTitle;
use HasDescription;
use HasKeywords;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'studios';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public static function primaryCacheKey(): string
{
return 'slug';
}
public function getUrl()
{
return route('studios.movies.index', $this->slug);
}
protected function titlePattern(): string
{
return Setting::get('site_studio_title', '');
}
protected function descriptionPattern(): string
{
return Setting::get('site_region_des', '');
}
protected function keywordsPattern(): string
{
return Setting::get('site_region_key', '');
}
public function generateSeoTags()
{
$seo_title = $this->getTitle();
$seo_des = Str::limit($this->getDescription(), 150, '...');
$seo_key = $this->getKeywords();
SEOMeta::setTitle($seo_title, false)
->setDescription($seo_des)
->addKeyword([$seo_key])
->setCanonical($this->getUrl())
->setPrev(request()->root())
->setPrev(request()->root());
// ->addMeta($meta, $value, 'property');
OpenGraph::setSiteName(setting('site_meta_siteName'))
->setTitle($seo_title, false)
->addProperty('type', 'movie')
->addProperty('locale', 'vi-VN')
->addProperty('url', $this->getUrl())
->setDescription($seo_des)
->addImages([$this->thumb_url, $this->poster_url]);
TwitterCard::setSite(setting('site_meta_siteName'))
->setTitle($seo_title, false)
->setType('movie')
->setImage($this->thumb_url)
->setDescription($seo_des)
->setUrl($this->getUrl());
// ->addValue($key, $value);
JsonLdMulti::newJsonLd()
->setSite(setting('site_meta_siteName'))
->setTitle($seo_title, false)
->setType('movie')
->setDescription($seo_des)
->setUrl($this->getUrl());
// ->addValue($key, $value);
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function movies()
{
return $this->belongsToMany(Movie::class);
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
}

191
src/Models/Tag.php Normal file
View File

@@ -0,0 +1,191 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Backpack\Settings\app\Models\Setting;
use Vsmov\Core\Contracts\TaxonomyInterface;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Vsmov\Core\Contracts\SeoInterface;
use Vsmov\Core\Traits\HasFactory;
use Vsmov\Core\Traits\HasTitle;
use Vsmov\Core\Traits\HasDescription;
use Vsmov\Core\Traits\HasKeywords;
use Vsmov\Core\Traits\HasUniqueName;
use Vsmov\Core\Traits\Sluggable;
use Illuminate\Support\Str;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\TwitterCard;
class Tag extends Model implements TaxonomyInterface, Cacheable, SeoInterface
{
use CrudTrait;
use Sluggable;
use HasUniqueName;
use HasFactory;
use HasCache;
use HasTitle;
use HasDescription;
use HasKeywords;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'tags';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public static function primaryCacheKey(): string
{
$site_routes = setting('site_routes_tag', '/tu-khoa/{tag}');
if (strpos($site_routes, '{tag}')) return 'slug';
if (strpos($site_routes, '{id}')) return 'id';
return 'slug';
}
public function getUrl()
{
$params = [];
$site_routes = setting('site_routes_tag', '/tu-khoa/{tag}');
if (strpos($site_routes, '{tag}')) $params['tag'] = $this->slug;
if (strpos($site_routes, '{id}')) $params['id'] = $this->id;
return route('tags.movies.index', $params);
}
protected function titlePattern(): string
{
return Setting::get('site_tag_title', '');
}
protected function descriptionPattern(): string
{
return Setting::get('site_tag_des', '');
}
protected function keywordsPattern(): string
{
return Setting::get('site_tag_key', '');
}
public function generateSeoTags()
{
$seo_title = $this->getTitle();
$seo_des = Str::limit($this->getDescription(), 150, '...');
$seo_key = $this->getKeywords();
$movie_thumb_url = '';
$movie_poster_url = '';
$updated_at = '';
if(count($this->movies)) {
$movie_thumb_url = filter_var($this->movies->last()->thumb_url, FILTER_VALIDATE_URL) ? $this->movies->last()->thumb_url : request()->root() . $this->movies->last()->thumb_url;
$movie_poster_url = filter_var($this->movies->last()->poster_url, FILTER_VALIDATE_URL) ? $this->movies->last()->poster_url : request()->root() . $this->movies->last()->poster_url;
$updated_at = $this->movies->last()->updated_at;
}
$getUrl = $this->getUrl();
$site_meta_siteName = setting('site_meta_siteName');
SEOMeta::setTitle($seo_title, false)
->setDescription($seo_des)
->addKeyword([$seo_key])
->setCanonical($getUrl)
->setPrev(request()->root())
->setPrev(request()->root());
OpenGraph::setSiteName($site_meta_siteName)
->setType('website')
->setTitle($seo_title, false)
->addProperty('locale', 'vi-VN')
->addProperty('updated_time', $updated_at)
->addProperty('url', $getUrl)
->setDescription($seo_des)
->addImages([$this->thumb_url, $this->poster_url]);
TwitterCard::setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('summary')
->setImage($movie_thumb_url)
->setDescription($seo_des)
->setUrl($getUrl);
JsonLdMulti::newJsonLd()
->setSite($site_meta_siteName)
->setTitle($seo_title, false)
->setType('WebPage')
->addValue('dateCreated', $updated_at)
->addValue('dateModified', $updated_at)
->addValue('datePublished', $updated_at)
->setDescription($seo_des)
->setImages([$movie_thumb_url, $movie_poster_url])
->setUrl($getUrl);
$breadcrumb = [];
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 1,
'name' => 'Home',
'item' => url('/')
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 2,
'name' => $this->name,
'item' => $getUrl
]);
array_push($breadcrumb, [
'@type' => 'ListItem',
'position' => 3,
'name' => "Trang " . (request()->get('page') ?: 1),
]);
JsonLdMulti::newJsonLd()
->setType('BreadcrumbList')
->addValue('name', '')
->addValue('description', '')
->addValue('itemListElement', $breadcrumb);
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function movies()
{
return $this->belongsToMany(Movie::class);
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
}

140
src/Models/Theme.php Normal file
View File

@@ -0,0 +1,140 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Vsmov\CachingModel\Contracts\Cacheable;
use Vsmov\CachingModel\HasCache;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Artisan;
use Vsmov\Core\Traits\HasFactory;
class Theme extends Model implements Cacheable
{
use CrudTrait;
use HasFactory;
use HasCache;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'themes';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
protected $casts = [
'value' => 'array',
];
public static function getActivatedTheme(): ?self
{
return Theme::where('active', true)->first() ?: Theme::first();
}
public function getVersionAttribute()
{
if (!\Composer\InstalledVersions::isInstalled($this->package_name)) {
return 'Unknown';
}
return \PackageVersions\Versions::getVersion($this->package_name);
}
public function getOptionsAttribute()
{
$allThemes = config('themes', []);
if (!isset($allThemes[strtolower($this->name)]['options'])) {
return [];
}
return $allThemes[strtolower($this->name)]['options'];
}
public function editBtn($crud = false)
{
return '<a href="' . backpack_url("theme/{$this->id}/edit") . '" class="btn btn-primary">Edit</a>';
}
public function deleteBtn($crud = false)
{
if ($this->getVersionAttribute() === 'Unknown') {
$template = <<<EOT
<form action="{actionRoute}" method="post" onsubmit="return confirm('Chắc chắn muốn xóa giao diện {display_name}?. ');" style="display: inline">
{csrfField}
<button class="btn btn-danger" type="submit">Delete</button>
</form>
EOT;
$html = str_replace("{actionRoute}", backpack_url("theme/{$this->id}/delete"), $template);
$html = str_replace("{csrfField}", csrf_field(), $html);
$html = str_replace("{display_name}", $this->display_name, $html);
return $html;
}
return '';
}
public function activeBtn($crud = false)
{
$template = <<<EOT
<form action="{actionRoute}" method="post" onsubmit="return confirm('Chắc chắn muốn kích hoạt giao diện {display_name}?');" style="display: inline">
{csrfField}
<button class="btn {btnType}" type="submit">{name}</button>
</form>
EOT;
$html = str_replace("{actionRoute}", backpack_url("theme/{$this->id}/active"), $template);
$html = str_replace("{csrfField}", csrf_field(), $html);
$html = str_replace("{display_name}", $this->display_name, $html);
if ($this->active) {
$html = str_replace("{name}", 'Re-Activate', $html);
$html = str_replace("{btnType}", 'btn-secondary', $html);
} else {
$html = str_replace("{name}", 'Activate', $html);
$html = str_replace("{btnType}", 'btn-primary', $html);
}
return $html;
}
public function resetBtn($crud = false)
{
$template = <<<EOT
<form action="{actionRoute}" method="post" onsubmit="return confirm('Chắc chắn muốn đặt về mặc định?');" style="display: inline">
{csrfField}
<button class="btn {btnType}" type="submit">{name}</button>
</form>
EOT;
$html = str_replace("{actionRoute}", backpack_url("theme/{$this->id}/reset"), $template);
$html = str_replace("{csrfField}", csrf_field(), $html);
$html = str_replace("{btnType}", 'btn-warning', $html);
$html = str_replace("{name}", 'Reset', $html);
return $html;
}
public function active()
{
static::where('active', true)->update(['active' => false]);
$publishTags = config('themes', [])[$this->name]['publishes'] ?? [];
foreach ($publishTags as $tag) {
Artisan::call('vendor:publish', [
'--tag' => $tag,
'--force' => true
]);
}
return $this->update(['active' => true]);
}
}

13
src/Models/User.php Normal file
View File

@@ -0,0 +1,13 @@
<?php
namespace Vsmov\Core\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use CrudTrait;
use HasRoles;
}