Initial commit
This commit is contained in:
290
src/Controllers/ThemeXingKongController.php
Executable file
290
src/Controllers/ThemeXingKongController.php
Executable file
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
|
||||
namespace VsMov\ThemeXingKong\Controllers;
|
||||
|
||||
use Backpack\Settings\app\Models\Setting;
|
||||
use Illuminate\Http\Request;
|
||||
use VsMov\Core\Models\Actor;
|
||||
use VsMov\Core\Models\Catalog;
|
||||
use VsMov\Core\Models\Category;
|
||||
use VsMov\Core\Models\Director;
|
||||
use VsMov\Core\Models\Episode;
|
||||
use VsMov\Core\Models\Movie;
|
||||
use VsMov\Core\Models\Region;
|
||||
use VsMov\Core\Models\Tag;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ThemeXingKongController
|
||||
{
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
if ($request['search'] || $request['filter']) {
|
||||
$data = Movie::when(!empty($request['filter']['category']), function ($movie) {
|
||||
$movie->whereHas('categories', function ($categories) {
|
||||
$categories->where('id', request('filter')['category']);
|
||||
});
|
||||
})->when(!empty($request['filter']['region']), function ($movie) {
|
||||
$movie->whereHas('regions', function ($regions) {
|
||||
$regions->where('id', request('filter')['region']);
|
||||
});
|
||||
})->when(!empty($request['filter']['year']), function ($movie) {
|
||||
$movie->where('publish_year', request('filter')['year']);
|
||||
})->when(!empty($request['filter']['type']), function ($movie) {
|
||||
$movie->where('type', request('filter')['type']);
|
||||
})->when(!empty($request['search']), function ($query) {
|
||||
$query->where(function ($query) {
|
||||
$query->whereRaw("MATCH(name, origin_name) AGAINST(? IN BOOLEAN MODE)", [request('search')]);
|
||||
});
|
||||
})->when(!empty($request['filter']['sort']), function ($movie) {
|
||||
if (request('filter')['sort'] == 'create') {
|
||||
return $movie->orderBy('created_at', 'desc');
|
||||
}
|
||||
if (request('filter')['sort'] == 'update') {
|
||||
return $movie->orderBy('updated_at', 'desc');
|
||||
}
|
||||
if (request('filter')['sort'] == 'year') {
|
||||
return $movie->orderBy('publish_year', 'desc');
|
||||
}
|
||||
if (request('filter')['sort'] == 'view') {
|
||||
return $movie->orderBy('view_total', 'desc');
|
||||
}
|
||||
})->paginate(get_theme_option('per_page_limit'));
|
||||
|
||||
return view('themes::themexingkong.catalog', [
|
||||
'data' => $data,
|
||||
'search' => $request['search'],
|
||||
'section_name' => "Tìm kiếm phim: $request->search"
|
||||
]);
|
||||
}
|
||||
return view('themes::themexingkong.index', [
|
||||
'title' => Setting::get('site_homepage_title')
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMovieOverview(Request $request)
|
||||
{
|
||||
/** @var Movie */
|
||||
$movie = Movie::fromCache()->find($request->movie ?: $request->id);
|
||||
|
||||
if (is_null($movie)) abort(404);
|
||||
|
||||
$movie->generateSeoTags();
|
||||
|
||||
$movie->increment('view_total', 1);
|
||||
$movie->increment('view_day', 1);
|
||||
$movie->increment('view_week', 1);
|
||||
$movie->increment('view_month', 1);
|
||||
|
||||
$movie_related_cache_key = 'movie_related:' . $movie->id;
|
||||
$movie_related = Cache::get($movie_related_cache_key);
|
||||
if (is_null($movie_related)) {
|
||||
$movie_related = $movie->categories[0]->movies()->inRandomOrder()->limit(get_theme_option('movie_related_limit', 10))->get();
|
||||
Cache::put($movie_related_cache_key, $movie_related, setting('site_cache_ttl', 5 * 60));
|
||||
}
|
||||
|
||||
return view('themes::themexingkong.single', [
|
||||
'currentMovie' => $movie,
|
||||
'title' => $movie->getTitle(),
|
||||
'movie_related' => $movie_related
|
||||
]);
|
||||
}
|
||||
|
||||
public function getEpisode(Request $request)
|
||||
{
|
||||
$movie = Movie::fromCache()->find($request->movie ?: $request->movie_id)->load('episodes');
|
||||
|
||||
if (is_null($movie)) abort(404);
|
||||
|
||||
/** @var Episode */
|
||||
$episode_id = $request->id;
|
||||
$episode = $movie->episodes->when($episode_id, function ($collection, $episode_id) {
|
||||
return $collection->where('id', $episode_id);
|
||||
})->firstWhere('slug', $request->episode);
|
||||
|
||||
if (is_null($episode)) abort(404);
|
||||
|
||||
$episode->generateSeoTags();
|
||||
|
||||
$movie->increment('view_total', 1);
|
||||
$movie->increment('view_day', 1);
|
||||
$movie->increment('view_week', 1);
|
||||
$movie->increment('view_month', 1);
|
||||
|
||||
$movie_related_cache_key = 'movie_related:' . $movie->id;
|
||||
$movie_related = Cache::get($movie_related_cache_key);
|
||||
if (is_null($movie_related)) {
|
||||
$movie_related = $movie->categories[0]->movies()->inRandomOrder()->limit(get_theme_option('movie_related_limit', 10))->get();
|
||||
Cache::put($movie_related_cache_key, $movie_related, setting('site_cache_ttl', 5 * 60));
|
||||
}
|
||||
|
||||
return view('themes::themexingkong.episode', [
|
||||
'currentMovie' => $movie,
|
||||
'movie_related' => $movie_related,
|
||||
'episode' => $episode,
|
||||
'title' => $episode->getTitle()
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMovieOfCategory(Request $request)
|
||||
{
|
||||
/** @var Category */
|
||||
$category = Category::fromCache()->find($request->category ?: $request->id);
|
||||
|
||||
if (is_null($category)) abort(404);
|
||||
|
||||
$category->generateSeoTags();
|
||||
|
||||
$movies = $category->movies()->orderBy('created_at', 'desc')->paginate(get_theme_option('per_page_limit'));
|
||||
|
||||
return view('themes::themexingkong.catalog', [
|
||||
'data' => $movies,
|
||||
'category' => $category,
|
||||
'title' => $category->seo_title ?: $category->getTitle(),
|
||||
'section_name' => "Phim thể loại $category->name"
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMovieOfRegion(Request $request)
|
||||
{
|
||||
/** @var Region */
|
||||
$region = Region::fromCache()->find($request->region ?: $request->id);
|
||||
|
||||
if (is_null($region)) abort(404);
|
||||
|
||||
$region->generateSeoTags();
|
||||
|
||||
$movies = $region->movies()->orderBy('created_at', 'desc')->paginate(get_theme_option('per_page_limit'));
|
||||
|
||||
return view('themes::themexingkong.catalog', [
|
||||
'data' => $movies,
|
||||
'region' => $region,
|
||||
'title' => $region->seo_title ?: $region->getTitle(),
|
||||
'section_name' => "Phim quốc gia $region->name"
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMovieOfActor(Request $request)
|
||||
{
|
||||
/** @var Actor */
|
||||
$actor = Actor::fromCache()->find($request->actor ?: $request->id);
|
||||
|
||||
if (is_null($actor)) abort(404);
|
||||
|
||||
$actor->generateSeoTags();
|
||||
|
||||
$movies = $actor->movies()->orderBy('created_at', 'desc')->paginate(get_theme_option('per_page_limit'));
|
||||
|
||||
return view('themes::themexingkong.catalog', [
|
||||
'data' => $movies,
|
||||
'person' => $actor,
|
||||
'title' => $actor->getTitle(),
|
||||
'section_name' => "Diễn viên $actor->name"
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMovieOfDirector(Request $request)
|
||||
{
|
||||
/** @var Director */
|
||||
$director = Director::fromCache()->find($request->director ?: $request->id);
|
||||
|
||||
if (is_null($director)) abort(404);
|
||||
|
||||
$director->generateSeoTags();
|
||||
|
||||
$movies = $director->movies()->orderBy('created_at', 'desc')->paginate(get_theme_option('per_page_limit'));
|
||||
|
||||
return view('themes::themexingkong.catalog', [
|
||||
'data' => $movies,
|
||||
'person' => $director,
|
||||
'title' => $director->getTitle(),
|
||||
'section_name' => "Đạo diễn $director->name"
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMovieOfTag(Request $request)
|
||||
{
|
||||
/** @var Tag */
|
||||
$tag = Tag::fromCache()->find($request->tag ?: $request->id);
|
||||
|
||||
if (is_null($tag)) abort(404);
|
||||
|
||||
$tag->generateSeoTags();
|
||||
|
||||
$movies = $tag->movies()->orderBy('created_at', 'desc')->paginate(get_theme_option('per_page_limit'));
|
||||
return view('themes::themexingkong.catalog', [
|
||||
'data' => $movies,
|
||||
'tag' => $tag,
|
||||
'title' => $tag->getTitle(),
|
||||
'section_name' => "Tags: $tag->name"
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMovieOfType(Request $request)
|
||||
{
|
||||
/** @var Catalog */
|
||||
$catalog = Catalog::fromCache()->find($request->type ?: $request->id);
|
||||
|
||||
if (is_null($catalog)) abort(404);
|
||||
|
||||
$catalog->generateSeoTags();
|
||||
|
||||
$cache_key = 'catalog:' . $catalog->id . ':page:' . ($request['page'] ?: 1);
|
||||
$movies = Cache::get($cache_key);
|
||||
if (is_null($movies)) {
|
||||
$value = explode('|', trim($catalog->value));
|
||||
[$relation_config, $field, $val, $sortKey, $alg] = array_merge($value, ['', 'is_copyright', 0, 'created_at', 'desc']);
|
||||
$relation_config = explode(',', $relation_config);
|
||||
|
||||
[$relation_table, $relation_field, $relation_val] = array_merge($relation_config, ['', '', '']);
|
||||
try {
|
||||
$movies = \VsMov\Core\Models\Movie::when($relation_table, function ($query) use ($relation_table, $relation_field, $relation_val, $field, $val) {
|
||||
$query->whereHas($relation_table, function ($rel) use ($relation_field, $relation_val, $field, $val) {
|
||||
$rel->where($relation_field, $relation_val)->where(array_combine(explode(",", $field), explode(",", $val)));
|
||||
});
|
||||
})->when(!$relation_table, function ($query) use ($field, $val) {
|
||||
$query->where(array_combine(explode(",", $field), explode(",", $val)));
|
||||
})
|
||||
->orderBy($sortKey, $alg)
|
||||
->paginate($catalog->paginate);
|
||||
|
||||
Cache::put($cache_key, $movies, setting('site_cache_ttl', 5 * 60));
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
return view('themes::themexingkong.catalog', [
|
||||
'data' => $movies,
|
||||
'section_name' => "Danh sách $catalog->name"
|
||||
]);
|
||||
}
|
||||
|
||||
public function reportEpisode(Request $request, $movie, $slug)
|
||||
{
|
||||
$movie = Movie::fromCache()->find($movie)->load('episodes');
|
||||
|
||||
$episode = $movie->episodes->when(request('id'), function ($collection) {
|
||||
return $collection->where('id', request('id'));
|
||||
})->firstWhere('slug', $slug);
|
||||
|
||||
$episode->update([
|
||||
'report_message' => request('message', ''),
|
||||
'has_report' => true
|
||||
]);
|
||||
|
||||
return response([], 204);
|
||||
}
|
||||
|
||||
public function rateMovie(Request $request, $movie)
|
||||
{
|
||||
|
||||
$movie = Movie::fromCache()->find($movie);
|
||||
|
||||
$movie->refresh()->increment('rating_count', 1, [
|
||||
'rating_star' => $movie->rating_star + ((int) request('rating') - $movie->rating_star) / ($movie->rating_count + 1)
|
||||
]);
|
||||
|
||||
return response([], 204);
|
||||
}
|
||||
}
|
||||
229
src/ThemeXingKongServiceProvider.php
Executable file
229
src/ThemeXingKongServiceProvider.php
Executable file
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
namespace VsMov\ThemeXingKong;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ThemeXingKongServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register()
|
||||
{
|
||||
$this->setupDefaultThemeCustomizer();
|
||||
}
|
||||
|
||||
public function boot()
|
||||
{
|
||||
$this->loadViewsFrom(__DIR__ . '/../resources/views/', 'themes');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/../resources/assets' => public_path('themes/xingkong')
|
||||
], 'xingkong-assets');
|
||||
|
||||
view()->composer('themes::themexingkong.*', function ($view) {
|
||||
$view->with('menu', \VsMov\Core\Models\Menu::getTree());
|
||||
});
|
||||
|
||||
view()->composer(['themes::themexingkong.inc.right_bar'], function ($view) {
|
||||
$tops = Cache::remember('site.movies.tops', setting('site_cache_ttl', 5 * 60), function () {
|
||||
$lists = preg_split('/[\n\r]+/', get_theme_option('hotest'));
|
||||
$data = [];
|
||||
foreach ($lists as $list) {
|
||||
if (trim($list)) {
|
||||
$list = explode('|', $list);
|
||||
[$label, $relation, $field, $val, $sortKey, $alg, $limit] = array_merge($list, ['Phim hot', '', 'type', 'series', 'view_total', 'desc', 4]);
|
||||
try {
|
||||
$data[] = [
|
||||
'label' => $label,
|
||||
'data' => \VsMov\Core\Models\Movie::when($relation, function ($query) use ($relation, $field, $val) {
|
||||
$query->whereHas($relation, function ($rel) use ($field, $val) {
|
||||
$rel->where($field, $val);
|
||||
});
|
||||
})
|
||||
->when(!$relation, function ($query) use ($field, $val) {
|
||||
$query->where($field, $val);
|
||||
})
|
||||
->orderBy($sortKey, $alg)
|
||||
->limit($limit)
|
||||
->get(),
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
# code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
});
|
||||
$view->with('tops', $tops);
|
||||
});
|
||||
}
|
||||
|
||||
protected function setupDefaultThemeCustomizer()
|
||||
{
|
||||
config(['themes' => array_merge(config('themes', []), [
|
||||
'xingkong' => [
|
||||
'name' => 'Theme XingKong',
|
||||
'author' => 'vsmov@gmail.com',
|
||||
'package_name' => 'vsmov/theme-xingkong',
|
||||
'publishes' => ['xingkong-assets'],
|
||||
'preview_image' => '',
|
||||
'options' => [
|
||||
[
|
||||
'name' => 'recommendations_limit',
|
||||
'label' => 'Recommended movies limit',
|
||||
'type' => 'number',
|
||||
'value' => 10,
|
||||
'wrapperAttributes' => [
|
||||
'class' => 'form-group col-md-4',
|
||||
],
|
||||
'tab' => 'List'
|
||||
],
|
||||
[
|
||||
'name' => 'per_page_limit',
|
||||
'label' => 'Pages limit',
|
||||
'type' => 'number',
|
||||
'value' => 30,
|
||||
'wrapperAttributes' => [
|
||||
'class' => 'form-group col-md-4',
|
||||
],
|
||||
'tab' => 'List'
|
||||
],
|
||||
[
|
||||
'name' => 'movie_related_limit',
|
||||
'label' => 'Movies related limit',
|
||||
'type' => 'number',
|
||||
'value' => 12,
|
||||
'wrapperAttributes' => [
|
||||
'class' => 'form-group col-md-4',
|
||||
],
|
||||
'tab' => 'List'
|
||||
],
|
||||
[
|
||||
'name' => 'latest',
|
||||
'label' => 'Home Page',
|
||||
'type' => 'code',
|
||||
'hint' => 'display_label|display_description|relation|find_by_field|value|sort_by_field|sort_algo|limit|show_more_url|section_template(default|with_top)',
|
||||
'value' => <<<EOT
|
||||
Phim chiếu rạp mới||is_shown_in_theater|1|created_at|desc|12|/danh-sach/phim-chieu-rap|default
|
||||
Phim bộ mới||type|series|updated_at|desc|10|/danh-sach/phim-bo|with_top
|
||||
Phim lẻ mới||type|single|updated_at|desc|10|/danh-sach/phim-le|with_top
|
||||
Phim hoạt hình mới|categories|slug|hoat-hinh|updated_at|desc|10|/the-loai/hoat-hinh|with_top
|
||||
EOT,
|
||||
'attributes' => [
|
||||
'rows' => 5
|
||||
],
|
||||
'tab' => 'List'
|
||||
],
|
||||
[
|
||||
'name' => 'hotest',
|
||||
'label' => 'Danh sách hot',
|
||||
'type' => 'code',
|
||||
'hint' => 'Label|relation|find_by_field|value|sort_by_field|sort_algo|limit',
|
||||
'value' => <<<EOT
|
||||
Phim sắp chiếu||status|trailer|publish_year|desc|8
|
||||
Top phim lẻ||type|single|view_week|desc|8
|
||||
Top phim bộ||type|series|view_week|desc|8
|
||||
EOT,
|
||||
'attributes' => [
|
||||
'rows' => 5
|
||||
],
|
||||
'tab' => 'List'
|
||||
],
|
||||
[
|
||||
'name' => 'additional_css',
|
||||
'label' => 'Additional CSS',
|
||||
'type' => 'code',
|
||||
'value' => "",
|
||||
'tab' => 'Custom CSS'
|
||||
],
|
||||
[
|
||||
'name' => 'body_attributes',
|
||||
'label' => 'Body attributes',
|
||||
'type' => 'text',
|
||||
'value' => '',
|
||||
'tab' => 'Custom CSS'
|
||||
],
|
||||
[
|
||||
'name' => 'additional_header_js',
|
||||
'label' => 'Header JS',
|
||||
'type' => 'code',
|
||||
'value' => "",
|
||||
'tab' => 'Custom JS'
|
||||
],
|
||||
[
|
||||
'name' => 'additional_body_js',
|
||||
'label' => 'Body JS',
|
||||
'type' => 'code',
|
||||
'value' => "",
|
||||
'tab' => 'Custom JS'
|
||||
],
|
||||
[
|
||||
'name' => 'additional_footer_js',
|
||||
'label' => 'Footer JS',
|
||||
'type' => 'code',
|
||||
'value' => "",
|
||||
'tab' => 'Custom JS'
|
||||
],
|
||||
[
|
||||
'name' => 'footer',
|
||||
'label' => 'Footer',
|
||||
'type' => 'code',
|
||||
'value' => <<<EOT
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="stui-foot clearfix">
|
||||
<p class="text-center hidden-xs">
|
||||
<a class="fed-font-xiv" href="#" target="_blank">Textlink</a>
|
||||
<span class="fed-font-xiv"> - </span>
|
||||
<a class="fed-font-xiv" href="#" target="_blank">Textlink</a>
|
||||
<span class="fed-font-xiv fed-hide-xs"> - </span>
|
||||
<a class="fed-font-xiv fed-hide-xs" href="#" target="_blank">Textlink</a>
|
||||
<span class="fed-font-xiv fed-hide-xs"> - </span>
|
||||
<a class="fed-font-xiv fed-hide-xs" href="#" target="_blank">Textlink</a>
|
||||
<span class="fed-font-xiv fed-hide-xs"> - </span>
|
||||
<a class="fed-font-xiv fed-hide-xs" href="#" target="_blank">Textlink</a>
|
||||
<span class="fed-font-xiv fed-hide-xs"> - </span>
|
||||
<a class="fed-font-xiv fed-hide-xs" href="#" target="_blank">Textlink</a>
|
||||
<span class="fed-font-xiv fed-hide-xs"> - </span>
|
||||
<a class="fed-font-xiv fed-hide-xs" href="#" target="_blank">Textlink</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="stui-foot clearfix">
|
||||
<div class="col-pd text-center hidden-xs">
|
||||
Dữ liệu phim miễn phí vĩnh viễn. Cập nhật nhanh, chất lượng cao, ổn định và lâu dài. Tốc độ phát cực nhanh với đường truyền băng thông cao, đảm bảo đáp ứng được lượng xem phim trực tuyến lớn. Đồng thời giúp nhà phát triển website phim giảm thiểu chi phí của các dịch vụ lưu trữ và stream.
|
||||
</div>
|
||||
<p class="share bdsharebuttonbox text-center margin-0 hidden-sm hidden-xs"></p>
|
||||
<p class="text-muted text-center visible-xs">Copyright © 2015-2024 <a href="/" target="_blank">VsMov</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
EOT,
|
||||
'tab' => 'Custom HTML'
|
||||
],
|
||||
[
|
||||
'name' => 'ads_header',
|
||||
'label' => 'Ads header',
|
||||
'type' => 'code',
|
||||
'value' => <<<EOT
|
||||
|
||||
EOT,
|
||||
'tab' => 'Ads'
|
||||
],
|
||||
[
|
||||
'name' => 'ads_catfish',
|
||||
'label' => 'Ads catfish',
|
||||
'type' => 'code',
|
||||
'value' => <<<EOT
|
||||
|
||||
EOT,
|
||||
'tab' => 'Ads'
|
||||
]
|
||||
],
|
||||
]
|
||||
])]);
|
||||
}
|
||||
}
|
||||
BIN
src/screenshot.png
Executable file
BIN
src/screenshot.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 615 KiB |
Reference in New Issue
Block a user