├── .gitignore
├── README.md
├── artisan
├── composer.json
├── config
└── config.php
├── database
├── factories
│ ├── ActorFactory.php
│ ├── CategoryFactory.php
│ ├── DirectorFactory.php
│ ├── EpisodeFactory.php
│ ├── MovieFactory.php
│ ├── RegionFactory.php
│ ├── StudioFactory.php
│ └── TagFactory.php
├── migrations
│ ├── 2015_08_04_131614_create_menus_table.php
│ ├── 2015_08_04_131614_create_settings_table.php
│ ├── 2020_03_31_114745_remove_backpackuser_model.php
│ ├── 2022_07_09_153613_create_themes_table.php
│ ├── 2022_07_10_125114_create_permission_tables.php
│ ├── 2022_07_10_153442_create_categories_table.php
│ ├── 2022_07_10_153517_create_actors_table.php
│ ├── 2022_07_10_153517_create_directors_table.php
│ ├── 2022_07_10_153517_create_regions_table.php
│ ├── 2022_07_10_153517_create_studios_table.php
│ ├── 2022_07_10_153517_create_tags_table.php
│ ├── 2022_07_10_153613_create_movies_table.php
│ ├── 2022_07_10_153614_create_episodes_table.php
│ ├── 2022_07_11_062342_create_actor_movie_table.php
│ ├── 2022_07_11_062342_create_category_movie_table.php
│ ├── 2022_07_11_062342_create_director_movie_table.php
│ ├── 2022_07_11_062342_create_movie_region_table.php
│ ├── 2022_07_11_062342_create_movie_studio_table.php
│ ├── 2022_07_11_062342_create_movie_tag_table.php
│ ├── 2022_11_02_071552_create_catalogs_table.php
│ └── 2023_06_06_185118_add_fulltext_index_to_movies.php
└── seeders
│ ├── CatalogsTableSeeder.php
│ ├── CategoriesTableSeeder.php
│ ├── MenusTableSeeder.php
│ ├── PermissionsSeeder.php
│ ├── RegionsTableSeeder.php
│ └── SettingsTableSeeder.php
├── draft.yml
├── package.json
├── resources
├── assets
│ └── js
│ │ ├── hls.min.js
│ │ ├── jwplayer-8.9.3.js
│ │ └── jwplayer.hlsjs.min.js
└── views
│ ├── core
│ ├── base
│ │ ├── columns
│ │ │ └── relationship.blade.php
│ │ ├── dashboard.blade.php
│ │ ├── fields
│ │ │ ├── checklist.blade.php
│ │ │ ├── ckfinder.blade.php
│ │ │ ├── fields_option.blade.php
│ │ │ ├── page_or_link.blade.php
│ │ │ ├── select2_from_array.blade.php
│ │ │ ├── select2_relationship_tags.blade.php
│ │ │ ├── select2_tags.blade.php
│ │ │ ├── select_from_table.blade.php
│ │ │ ├── select_theme.blade.php
│ │ │ └── update_fields_option.blade.php
│ │ └── inc
│ │ │ ├── main_header.blade.php
│ │ │ ├── sidebar_content.blade.php
│ │ │ └── topbar_right_content.blade.php
│ ├── crud
│ │ ├── buttons
│ │ │ └── bulk_delete.blade.php
│ │ └── filters
│ │ │ ├── select2.blade.php
│ │ │ └── simple.blade.php
│ ├── movies
│ │ ├── columns
│ │ │ └── column_movie_info.blade.php
│ │ ├── create.blade.php
│ │ ├── edit.blade.php
│ │ └── inc
│ │ │ └── episode.blade.php
│ └── sitemap
│ │ └── styles.blade.php
│ └── themes
│ └── layout.blade.php
├── routes
└── admin.php
├── src
├── Console
│ ├── ChangeDomainEpisodeCommand.php
│ ├── CreateUser.php
│ ├── GenerateMenuCommand.php
│ └── InstallCommand.php
├── Contracts
│ ├── HasUrlInterface.php
│ ├── SeoInterface.php
│ └── TaxonomyInterface.php
├── Controllers
│ ├── Admin
│ │ ├── ActorCrudController.php
│ │ ├── AdminController.php
│ │ ├── CatalogCrudController.php
│ │ ├── CategoryCrudController.php
│ │ ├── DirectorCrudController.php
│ │ ├── EpisodeCrudController.php
│ │ ├── MenuCrudController.php
│ │ ├── MovieCrudController.php
│ │ ├── PluginController.php
│ │ ├── QuickActionController.php
│ │ ├── RegionCrudController.php
│ │ ├── SiteMapController.php
│ │ ├── StudioCrudController.php
│ │ ├── TagCrudController.php
│ │ └── ThemeManagementController.php
│ └── Controller.php
├── Helpers
│ └── helpers.php
├── Middleware
│ ├── CKFinderAuth.php
│ ├── EncryptCookies.php
│ └── VerifyCsrfToken.php
├── Models
│ ├── Actor.php
│ ├── Catalog.php
│ ├── Category.php
│ ├── Director.php
│ ├── Episode.php
│ ├── Menu.php
│ ├── Movie.php
│ ├── Region.php
│ ├── Studio.php
│ ├── Tag.php
│ ├── Theme.php
│ └── User.php
├── OphimServiceProvider.php
├── Policies
│ ├── ActorPolicy.php
│ ├── CatalogPolicy.php
│ ├── CategoryPolicy.php
│ ├── CrawlSchedulePolicy.php
│ ├── DirectorPolicy.php
│ ├── EpisodePolicy.php
│ ├── MenuPolicy.php
│ ├── MoviePolicy.php
│ ├── PermissionPolicy.php
│ ├── RegionPolicy.php
│ ├── RolePolicy.php
│ ├── StudioPolicy.php
│ ├── TagPolicy.php
│ └── UserPolicy.php
├── Requests
│ ├── ActorRequest.php
│ ├── CatalogRequest.php
│ ├── CategoryRequest.php
│ ├── CrawlScheduleRequest.php
│ ├── DirectorRequest.php
│ ├── MenuRequest.php
│ ├── MovieRequest.php
│ ├── RegionRequest.php
│ ├── StudioRequest.php
│ └── TagRequest.php
├── Rules
│ └── UniqueName.php
├── Theme.php
└── Traits
│ ├── ActorLog.php
│ ├── HasDescription.php
│ ├── HasFactory.php
│ ├── HasKeywords.php
│ ├── HasTitle.php
│ ├── HasUniqueName.php
│ ├── Operations
│ └── BulkDeleteOperation.php
│ └── Sluggable.php
├── tests
└── databases
│ └── DatabaseTesting.php
└── webpack.mix.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | /node_modules
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Server Requirements:
2 | - Laravel Framework 8.
3 | - PHP 7.3 or higher.
4 | + Configure `php.ini`:
5 |
6 | ```
7 | max_input_vars=100000
8 | ```
9 | - MySQL 5.7 or higher.
10 | # Add-on & Themes:
11 | - Home: [OPhimCMS.CC](https://opcms.cc)
12 | - Admin: [Demo.OPhimCMS.CC/admin](https://demo.ophimcms.cc/admin)
13 | - Free Movies Data: [OPhim.Movie](https://ophim.movie)
14 |
15 | - Add-on:
16 | - [OPhim Crawler](https://github.com/hacoidev/ophim-crawler)
17 | - Theme: [MORE...](https://opcms.cc)
18 |
19 | # Installation:
20 | 1. CD to project root and run: `composer require hacoidev/ophim-core -W`
21 | 2. Configuration your database connection information in file `.env`
22 | 3. Then, run command: `php artisan ophim:install`
23 | 4. Change app\Models\User:
24 | ```php
25 | use Ophim\Core\Models\User as OphimUser;
26 |
27 | class User extends OphimUser {
28 | use HasApiTokens, HasFactory, Notifiable;
29 | // ...
30 | }
31 | ```
32 | 5. Create new user by command: `php artisan ophim:user`
33 |
34 | 6. Remove this route definition in routes/web.php
35 | ```php
36 | Route::get('/', function () {
37 | return view('welcome');
38 | });
39 | ```
40 | 7. Run `php artisan optimize:clear`
41 |
42 | # Update:
43 | 1. CD to project root and run: `composer update hacoidev/ophim-core -W`
44 | 2. Then, run command: `php artisan ophim:install`
45 | 3. Run `php artisan optimize:clear`
46 | 4. Clear PHP Opcache in server (if enabled)
47 |
48 | # Note
49 | - Configure a production environment file `.env`
50 | + `APP_NAME=your_app_name`
51 | + `APP_ENV=production`
52 | + `APP_DEBUG=false`
53 | + `APP_URL=https://your-domain.com`
54 | - Configure timezone `/config/app.php`
55 | + `'timezone' => 'Asia/Ho_Chi_Minh'`
56 | + `'locale' => 'vi'`
57 |
58 | - Command CMS
59 | + `php artisan ophim:menu:generate` : Generate menu
60 | + `php artisan ophim:episode:change_domain` : Change episode domain play stream
61 |
62 | # Command:
63 | - Generate menu categories & regions: `php artisan ophim:menu:generate`
64 |
65 | # Reset view counter:
66 | - Setup crontab, add this entry:
67 | ```
68 | * * * * * cd /path/to/project && php artisan schedule:run >> /dev/null 2>&1
69 | ```
70 |
--------------------------------------------------------------------------------
/artisan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | make(Illuminate\Contracts\Console\Kernel::class);
34 |
35 | $status = $kernel->handle(
36 | $input = new Symfony\Component\Console\Input\ArgvInput,
37 | new Symfony\Component\Console\Output\ConsoleOutput
38 | );
39 |
40 | /*
41 | |--------------------------------------------------------------------------
42 | | Shutdown The Application
43 | |--------------------------------------------------------------------------
44 | |
45 | | Once Artisan has finished running, we will fire off the shutdown events
46 | | so that any final work may be done by the application before we shut
47 | | down the process. This is the last thing to happen to the request.
48 | |
49 | */
50 |
51 | $kernel->terminate($input, $status);
52 |
53 | exit($status);
54 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hacoidev/ophim-core",
3 | "description": "Ophim's core features",
4 | "type": "library",
5 | "authors": [
6 | {
7 | "name": "hacoidev",
8 | "email": "hacoi.dev@gmail.com"
9 | }
10 | ],
11 | "require": {
12 | "laravel/framework": "^6|^7|^8",
13 | "ckfinder/ckfinder-laravel-package": "v3.5.2.1",
14 | "hacoidev/laravel-caching-model": "^1.0.0",
15 | "hacoidev/crud": "^1.0.0",
16 | "hacoidev/settings": "^1.0.0",
17 | "hacoidev/permissionmanager": "^1.0.0",
18 | "spatie/laravel-sitemap": "^5.8",
19 | "artesaos/seotools": "^v0.22.1"
20 | },
21 | "license": "MIT",
22 | "autoload": {
23 | "psr-4": {
24 | "Ophim\\Core\\": "src/",
25 | "Ophim\\Core\\Database\\Factories\\": "database/factories/",
26 | "Ophim\\Core\\Database\\Seeders\\": "database/seeders/"
27 | }
28 | },
29 | "extra": {
30 | "laravel": {
31 | "providers": [
32 | "Ophim\\Core\\OphimServiceProvider"
33 | ]
34 | }
35 | },
36 | "minimum-stability": "stable"
37 | }
38 |
--------------------------------------------------------------------------------
/config/config.php:
--------------------------------------------------------------------------------
1 | explode('@', \PackageVersions\Versions::getVersion('hacoidev/ophim-core') ?? 0)[0],
5 | 'episodes' => [
6 | 'types' => [
7 | 'embed' => 'Nhúng',
8 | 'mp4' => 'MP4',
9 | 'm3u8' => 'M3U8'
10 | ]
11 | ],
12 | 'ckfinder' => [
13 | 'loadRoutes' => false,
14 | 'backends' => [
15 | 'name' => 'default',
16 | 'adapter' => 'local',
17 | 'baseUrl' => '/storage/',
18 | 'root' => public_path('/storage/'),
19 | 'chmodFiles' => 0777,
20 | 'chmodFolders' => 0755,
21 | 'filesystemEncoding' => 'UTF-8'
22 | ]
23 | ]
24 | ];
25 |
--------------------------------------------------------------------------------
/database/factories/ActorFactory.php:
--------------------------------------------------------------------------------
1 | $name = $this->faker->name,
27 | 'slug' => Str::slug($name),
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/database/factories/CategoryFactory.php:
--------------------------------------------------------------------------------
1 | $name = $this->faker->name,
27 | 'slug' => Str::slug($name),
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/database/factories/DirectorFactory.php:
--------------------------------------------------------------------------------
1 | $name = $this->faker->name,
27 | 'slug' => Str::slug($name),
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/database/factories/EpisodeFactory.php:
--------------------------------------------------------------------------------
1 | $name = rand(1, 5),
27 | 'slug' => Str::slug('tap-' . $name),
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/database/factories/MovieFactory.php:
--------------------------------------------------------------------------------
1 | $name = $this->faker->name,
27 | 'origin_name' => $name,
28 | 'slug' => Str::slug($name.microtime(true)),
29 | ];
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/database/factories/RegionFactory.php:
--------------------------------------------------------------------------------
1 | $name = $this->faker->name,
27 | 'slug' => Str::slug($name),
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/database/factories/StudioFactory.php:
--------------------------------------------------------------------------------
1 | $name = $this->faker->name,
27 | 'slug' => Str::slug($name),
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/database/factories/TagFactory.php:
--------------------------------------------------------------------------------
1 | $name = $this->faker->name,
27 | 'slug' => Str::slug($name),
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/database/migrations/2015_08_04_131614_create_menus_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('name', 100);
19 | $table->string('type', 20)->nullable();
20 | $table->string('link', 255)->nullable();
21 | $table->integer('parent_id')->unsigned()->nullable();
22 | $table->integer('lft')->unsigned()->nullable();
23 | $table->integer('rgt')->unsigned()->nullable();
24 | $table->integer('depth')->unsigned()->nullable();
25 | $table->timestamps();
26 | $table->softDeletes();
27 | });
28 | }
29 |
30 | /**
31 | * Reverse the migrations.
32 | *
33 | * @return void
34 | */
35 | public function down()
36 | {
37 | Schema::dropIfExists('menus');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/database/migrations/2015_08_04_131614_create_settings_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('key')->unique();
19 | $table->string('name');
20 | $table->string('description')->nullable();
21 | $table->text('value')->nullable();
22 | $table->text('field');
23 | $table->string('group')->nullable()->index();
24 | $table->boolean('active')->index();
25 | $table->timestamps();
26 |
27 | $table->index(['group', 'active']);
28 | });
29 | }
30 |
31 | /**
32 | * Reverse the migrations.
33 | *
34 | * @return void
35 | */
36 | public function down()
37 | {
38 | Schema::dropIfExists('settings');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/database/migrations/2020_03_31_114745_remove_backpackuser_model.php:
--------------------------------------------------------------------------------
1 | replaceModels($model_has_roles);
23 | }
24 | if (\Illuminate\Support\Facades\Schema::hasTable($model_has_permissions)) {
25 | $this->replaceModels($model_has_permissions);
26 | }
27 | }
28 |
29 | public function replaceModels($table_name)
30 | {
31 | Log::info('Replacing BackpackUser model in '.$table_name);
32 |
33 | // if you've ended up with duplicate entries (both for App\User and App\Models\BackpackUser)
34 | // we can just delete them
35 | $userEntries = DB::table($table_name)
36 | ->where('model_type', "App\User")
37 | ->get();
38 |
39 | foreach ($userEntries as $entry) {
40 | DB::table($table_name)
41 | ->where('role_id', $entry->role_id)
42 | ->where('model_type', 'App\Models\BackpackUser')
43 | ->where('model_id', $entry->model_id)
44 | ->delete();
45 | }
46 |
47 | // for the rest of them, we can just replace the BackpackUser model with User
48 | DB::table($table_name)
49 | ->where('model_type', "App\Models\BackpackUser")
50 | ->update([
51 | 'model_type' => "App\User",
52 | ]);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_09_153613_create_themes_table.php:
--------------------------------------------------------------------------------
1 | id();
18 | $table->string('name')->index();
19 | $table->string('display_name');
20 | $table->string('preview_image')->nullable();
21 | $table->string('author');
22 | $table->string('package_name');
23 | $table->text('value')->nullable();
24 | $table->boolean('active')->default(false);
25 | $table->timestamps();
26 | });
27 | }
28 |
29 | /**
30 | * Reverse the migrations.
31 | *
32 | * @return void
33 | */
34 | public function down()
35 | {
36 | Schema::dropIfExists('themes');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_10_153442_create_categories_table.php:
--------------------------------------------------------------------------------
1 | bigIncrements('id');
18 | $table->string('name')->unique();
19 | $table->string('slug')->unique()->index();
20 | $table->string('seo_title')->nullable();
21 | $table->string('seo_des')->nullable();
22 | $table->string('seo_key')->nullable();
23 | $table->unsignedBigInteger('user_id')->nullable()->index();
24 | $table->string('user_name')->nullable();
25 | $table->timestamps();
26 | });
27 | }
28 |
29 | /**
30 | * Reverse the migrations.
31 | *
32 | * @return void
33 | */
34 | public function down()
35 | {
36 | Schema::dropIfExists('categories');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_10_153517_create_actors_table.php:
--------------------------------------------------------------------------------
1 | id();
18 | $table->string('name');
19 | $table->string('name_md5')->unique();
20 | $table->string('slug')->index();
21 | $table->enum('gender', ['male', 'female', 'other'])->nullable();
22 | $table->string('bio')->nullable();
23 | $table->string('thumb_url', 2048)->nullable();
24 | $table->string('seo_title')->nullable();
25 | $table->string('seo_des')->nullable();
26 | $table->string('seo_key')->nullable();
27 | $table->timestamps();
28 | });
29 | }
30 |
31 | /**
32 | * Reverse the migrations.
33 | *
34 | * @return void
35 | */
36 | public function down()
37 | {
38 | Schema::dropIfExists('actors');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_10_153517_create_directors_table.php:
--------------------------------------------------------------------------------
1 | id();
18 | $table->string('name');
19 | $table->string('name_md5')->unique();
20 | $table->string('slug')->index();
21 | $table->enum('gender', ['male', 'female', 'other'])->nullable();
22 | $table->string('bio')->nullable();
23 | $table->string('thumb_url', 2048)->nullable();
24 | $table->string('seo_title')->nullable();
25 | $table->string('seo_des')->nullable();
26 | $table->string('seo_key')->nullable();
27 | $table->timestamps();
28 | });
29 | }
30 |
31 | /**
32 | * Reverse the migrations.
33 | *
34 | * @return void
35 | */
36 | public function down()
37 | {
38 | Schema::dropIfExists('directors');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_10_153517_create_regions_table.php:
--------------------------------------------------------------------------------
1 | bigIncrements('id');
18 | $table->string('name')->unique();
19 | $table->string('slug')->unique()->index();
20 | $table->string('seo_title')->nullable();
21 | $table->string('seo_des')->nullable();
22 | $table->string('seo_key')->nullable();
23 | $table->unsignedBigInteger('user_id')->nullable()->index();
24 | $table->string('user_name')->nullable();
25 | $table->timestamps();
26 | });
27 | }
28 |
29 | /**
30 | * Reverse the migrations.
31 | *
32 | * @return void
33 | */
34 | public function down()
35 | {
36 | Schema::dropIfExists('regions');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_10_153517_create_studios_table.php:
--------------------------------------------------------------------------------
1 | id();
18 | $table->string('name');
19 | $table->string('name_md5')->unique();
20 | $table->string('slug')->index();
21 | $table->string('thumb_url', 2048)->nullable();
22 | $table->string('seo_title')->nullable();
23 | $table->string('seo_des')->nullable();
24 | $table->string('seo_key')->nullable();
25 | $table->timestamps();
26 | });
27 | }
28 |
29 | /**
30 | * Reverse the migrations.
31 | *
32 | * @return void
33 | */
34 | public function down()
35 | {
36 | Schema::dropIfExists('studios');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_10_153517_create_tags_table.php:
--------------------------------------------------------------------------------
1 | id();
18 | $table->string('name');
19 | $table->string('name_md5')->unique();
20 | $table->string('slug')->index();
21 | $table->string('seo_title')->nullable();
22 | $table->string('seo_des')->nullable();
23 | $table->string('seo_key')->nullable();
24 | $table->timestamps();
25 | });
26 | }
27 |
28 | /**
29 | * Reverse the migrations.
30 | *
31 | * @return void
32 | */
33 | public function down()
34 | {
35 | Schema::dropIfExists('tags');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_10_153613_create_movies_table.php:
--------------------------------------------------------------------------------
1 | id();
18 | $table->string('name', 1024);
19 | $table->string('origin_name', 1024);
20 | $table->string('slug')->unique();
21 | $table->text('content')->nullable();
22 | $table->string('thumb_url', 2048)->nullable();
23 | $table->string('poster_url', 2048)->nullable();
24 | $table->enum('type', ['single', 'series']);
25 | $table->enum('status', ['trailer', 'ongoing', 'completed']);
26 | $table->string('trailer_url', 2048)->nullable();
27 | $table->string('episode_time')->nullable();
28 | $table->string('episode_current')->nullable();
29 | $table->string('episode_total')->nullable();
30 | $table->string('quality')->nullable()->default('HD');
31 | $table->string('language')->nullable()->default('Vietsub');
32 | $table->string('notify', 512)->nullable();
33 | $table->string('showtimes', 512)->nullable();
34 | $table->integer('publish_year')->index()->nullable();
35 | $table->boolean('is_shown_in_theater')->default(false);
36 | $table->boolean('is_recommended')->default(false);
37 | $table->boolean('is_copyright')->default(false);
38 | $table->boolean('is_sensitive_content')->default(false);
39 |
40 | $table->integer('episode_server_count')->default(0);
41 | $table->integer('episode_data_count')->default(0);
42 |
43 | $table->integer('view_total')->default(0);
44 | $table->integer('view_day')->default(0);
45 | $table->integer('view_week')->default(0);
46 | $table->integer('view_month')->default(0);
47 | $table->integer('rating_count')->default(0);
48 | $table->decimal('rating_star', 3, 1)->default(0);
49 |
50 | $table->string('update_handler', 1024)->nullable();
51 | $table->string('update_identity', 2048)->nullable();
52 | $table->string('update_checksum', 2048)->nullable();
53 |
54 | $table->unsignedBigInteger('user_id')->nullable()->index();
55 | $table->string('user_name')->nullable();
56 | $table->timestamps();
57 | });
58 | }
59 |
60 | /**
61 | * Reverse the migrations.
62 | *
63 | * @return void
64 | */
65 | public function down()
66 | {
67 | Schema::dropIfExists('movies');
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_10_153614_create_episodes_table.php:
--------------------------------------------------------------------------------
1 | bigIncrements('id');
18 |
19 | $table->unsignedBigInteger('movie_id')->index();
20 | $table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
21 |
22 | $table->string('server');
23 | $table->string('name');
24 | $table->string('slug');
25 | $table->string('type');
26 | $table->string('link')->nullable();
27 | $table->boolean('has_report')->default(false);
28 | $table->string('report_message', 512)->nullable();
29 | $table->timestamps();
30 |
31 | $table->index(['movie_id', 'slug']);
32 | });
33 | }
34 |
35 | /**
36 | * Reverse the migrations.
37 | *
38 | * @return void
39 | */
40 | public function down()
41 | {
42 | Schema::dropIfExists('episodes');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_11_062342_create_actor_movie_table.php:
--------------------------------------------------------------------------------
1 | unsignedBigInteger('movie_id')->index();
18 | $table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
19 |
20 | $table->unsignedBigInteger('actor_id')->index();
21 | $table->foreign('actor_id')->references('id')->on('actors')->onDelete('cascade');
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::dropIfExists('actor_movie');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_11_062342_create_category_movie_table.php:
--------------------------------------------------------------------------------
1 | unsignedBigInteger('movie_id')->index();
18 | $table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
19 |
20 | $table->unsignedBigInteger('category_id')->index();
21 | $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::dropIfExists('category_movie');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_11_062342_create_director_movie_table.php:
--------------------------------------------------------------------------------
1 | unsignedBigInteger('movie_id')->index();
18 | $table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
19 |
20 | $table->unsignedBigInteger('director_id')->index();
21 | $table->foreign('director_id')->references('id')->on('directors')->onDelete('cascade');
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::dropIfExists('director_movie');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_11_062342_create_movie_region_table.php:
--------------------------------------------------------------------------------
1 | unsignedBigInteger('movie_id')->index();
18 | $table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
19 |
20 | $table->unsignedBigInteger('region_id')->index();
21 | $table->foreign('region_id')->references('id')->on('regions')->onDelete('cascade');
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::dropIfExists('movie_region');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_11_062342_create_movie_studio_table.php:
--------------------------------------------------------------------------------
1 | unsignedBigInteger('movie_id')->index();
18 | $table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
19 |
20 | $table->unsignedBigInteger('studio_id')->index();
21 | $table->foreign('studio_id')->references('id')->on('studios')->onDelete('cascade');
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::dropIfExists('movie_studio');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_11_062342_create_movie_tag_table.php:
--------------------------------------------------------------------------------
1 | unsignedBigInteger('movie_id')->index();
18 | $table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
19 |
20 | $table->unsignedBigInteger('tag_id')->index();
21 | $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::dropIfExists('movie_tag');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/migrations/2022_11_02_071552_create_catalogs_table.php:
--------------------------------------------------------------------------------
1 | id();
18 | $table->string('name')->unique();
19 | $table->string('slug')->unique()->index();
20 | $table->integer('paginate')->default(20);
21 | $table->string('value')->nullable();
22 | $table->string('seo_title')->nullable();
23 | $table->string('seo_des')->nullable();
24 | $table->string('seo_key')->nullable();
25 | $table->timestamps();
26 | });
27 | }
28 |
29 | /**
30 | * Reverse the migrations.
31 | *
32 | * @return void
33 | */
34 | public function down()
35 | {
36 | Schema::dropIfExists('catalogs');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/database/migrations/2023_06_06_185118_add_fulltext_index_to_movies.php:
--------------------------------------------------------------------------------
1 | 'Phim mới',
21 | 'slug' => 'phim-moi',
22 | 'paginate' => 20,
23 | 'value' => '|is_copyright|0|updated_at|desc',
24 | 'seo_title' => 'Title Phim mới',
25 | 'seo_des' => 'Des Phim mới',
26 | 'seo_key' => 'Key Phim mới',
27 | ],
28 | [
29 | 'name' => 'Phim bộ',
30 | 'slug' => 'phim-bo',
31 | 'paginate' => 20,
32 | 'value' => '|type|series|updated_at|desc',
33 | 'seo_title' => 'Title Phim bộ',
34 | 'seo_des' => 'Des Phim bộ',
35 | 'seo_key' => 'Key Phim bộ',
36 | ],
37 | [
38 | 'name' => 'Phim lẻ',
39 | 'slug' => 'phim-le',
40 | 'paginate' => 20,
41 | 'value' => '|type|single|updated_at|desc',
42 | 'seo_title' => 'Title Phim lẻ',
43 | 'seo_des' => 'Des Phim lẻ',
44 | 'seo_key' => 'Key Phim lẻ',
45 | ]
46 | ];
47 |
48 | foreach ($catalogs as $index => $catalog) {
49 | $result = Catalog::firstOrCreate(collect($catalog)->only('slug')->toArray(), collect($catalog)->except('slug')->toArray());
50 |
51 | if (!$result) {
52 | $this->command->info("Insert failed at record $index");
53 |
54 | return;
55 | }
56 | }
57 |
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/database/seeders/CategoriesTableSeeder.php:
--------------------------------------------------------------------------------
1 | "Hành Động",
21 | "slug" => "hanh-dong",
22 | ],
23 | [
24 | "name" => "Tình Cảm",
25 | "slug" => "tinh-cam",
26 | ],
27 | [
28 | "name" => "Hài Hước",
29 | "slug" => "hai-huoc",
30 | ],
31 | [
32 | "name" => "Cổ Trang",
33 | "slug" => "co-trang",
34 | ],
35 | [
36 | "name" => "Tâm Lý",
37 | "slug" => "tam-ly",
38 | ],
39 | [
40 | "name" => "Hình Sự",
41 | "slug" => "hinh-su",
42 | ],
43 | [
44 | "name" => "Chiến Tranh",
45 | "slug" => "chien-tranh",
46 | ],
47 | [
48 | "name" => "Thể Thao",
49 | "slug" => "the-thao",
50 | ],
51 | [
52 | "name" => "Võ Thuật",
53 | "slug" => "vo-thuat",
54 | ],
55 | [
56 | "name" => "Viễn Tưởng",
57 | "slug" => "vien-tuong",
58 | ],
59 | [
60 | "name" => "Phiêu Lưu",
61 | "slug" => "phieu-luu",
62 | ],
63 | [
64 | "name" => "Khoa Học",
65 | "slug" => "khoa-hoc",
66 | ],
67 | [
68 | "name" => "Kinh Dị",
69 | "slug" => "kinh-di",
70 | ],
71 | [
72 | "name" => "Âm Nhạc",
73 | "slug" => "am-nhac",
74 | ],
75 | [
76 | "name" => "Thần Thoại",
77 | "slug" => "than-thoai",
78 | ],
79 | [
80 | "name" => "Tài Liệu",
81 | "slug" => "tai-lieu",
82 | ],
83 | [
84 | "name" => "Gia Đình",
85 | "slug" => "gia-dinh",
86 | ],
87 | [
88 | "name" => "Chính kịch",
89 | "slug" => "chinh-kich",
90 | ],
91 | [
92 | "name" => "Bí ẩn",
93 | "slug" => "bi-an",
94 | ],
95 | [
96 | "name" => "Học Đường",
97 | "slug" => "hoc-duong",
98 | ],
99 | [
100 | "name" => "Kinh Điển",
101 | "slug" => "kinh-dien",
102 | ],
103 | [
104 | "name" => "Phim 18+",
105 | "slug" => "phim-18",
106 | ],
107 | ];
108 |
109 | foreach ($categories as $index => $category) {
110 | $result = Category::updateOrCreate($category);
111 |
112 | if (!$result) {
113 | $this->command->info("Insert failed at record $index.");
114 |
115 | return;
116 | }
117 | }
118 |
119 | $this->command->info('Inserted ' . count($categories) . ' categories.');
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/database/seeders/MenusTableSeeder.php:
--------------------------------------------------------------------------------
1 | 'Trang chủ', 'link' => '/', 'type' => 'internal_link']);
24 | $categoryGroup = Menu::firstOrCreate(['name' => 'Thể loại', 'link' => '#', 'type' => 'internal_link']);
25 | $categories = Category::all();
26 | foreach ($categories as $category) {
27 | Menu::updateOrCreate([
28 | 'name' => $category->name,
29 | ], [
30 | 'link' => $category->getUrl(false),
31 | 'type' => 'internal_link',
32 | 'parent_id' => $categoryGroup->id
33 | ]);
34 | }
35 |
36 | $regionGroup = Menu::firstOrCreate(['name' => 'Quốc gia', 'link' => '#', 'type' => 'internal_link']);
37 | $regions = Region::all();
38 | foreach ($regions as $region) {
39 | Menu::updateOrCreate([
40 | 'name' => $region->name,
41 | ], [
42 | 'link' => $region->getUrl(false),
43 | 'type' => 'internal_link',
44 | 'parent_id' => $regionGroup->id
45 | ]);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/database/seeders/PermissionsSeeder.php:
--------------------------------------------------------------------------------
1 | "Admin", 'guard_name' => 'backpack']);
83 | foreach ($permissions as $index => $permission) {
84 | $result = Permission::firstOrCreate([
85 | 'name' => $permission,
86 | 'guard_name' => 'backpack'
87 | ]);
88 |
89 | $admin->givePermissionTo($permission);
90 |
91 | if (!$result) {
92 | $this->command->info("Insert failed at record $index.");
93 |
94 | return;
95 | }
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/database/seeders/RegionsTableSeeder.php:
--------------------------------------------------------------------------------
1 | "Trung Quốc",
22 | "slug" => "trung-quoc",
23 | ],
24 | [
25 | "name" => "Hàn Quốc",
26 | "slug" => "han-quoc",
27 | ],
28 | [
29 | "name" => "Nhật Bản",
30 | "slug" => "nhat-ban",
31 | ],
32 | [
33 | "name" => "Thái Lan",
34 | "slug" => "thai-lan",
35 | ],
36 | [
37 | "name" => "Âu Mỹ",
38 | "slug" => "au-my",
39 | ],
40 | [
41 | "name" => "Đài Loan",
42 | "slug" => "dai-loan",
43 | ],
44 | [
45 | "name" => "Hồng Kông",
46 | "slug" => "hong-kong",
47 | ],
48 | [
49 | "name" => "Ấn Độ",
50 | "slug" => "an-do",
51 | ],
52 | [
53 | "name" => "Anh",
54 | "slug" => "anh",
55 | ],
56 | [
57 | "name" => "Pháp",
58 | "slug" => "phap",
59 | ],
60 | [
61 | "name" => "Canada",
62 | "slug" => "canada",
63 | ],
64 | [
65 | "name" => "Quốc Gia Khác",
66 | "slug" => "quoc-gia-khac",
67 | ],
68 | [
69 | "name" => "Đức",
70 | "slug" => "duc",
71 | ],
72 | [
73 | "name" => "Tây Ban Nha",
74 | "slug" => "tay-ban-nha",
75 | ],
76 | [
77 | "name" => "Thổ Nhĩ Kỳ",
78 | "slug" => "tho-nhi-ky",
79 | ],
80 | [
81 | "name" => "Hà Lan",
82 | "slug" => "ha-lan",
83 | ],
84 | [
85 | "name" => "Indonesia",
86 | "slug" => "indonesia",
87 | ],
88 | [
89 | "name" => "Nga",
90 | "slug" => "nga",
91 | ],
92 | [
93 | "name" => "Mexico",
94 | "slug" => "mexico",
95 | ],
96 | [
97 | "name" => "Ba lan",
98 | "slug" => "ba-lan",
99 | ],
100 | [
101 | "name" => "Úc",
102 | "slug" => "uc",
103 | ],
104 | [
105 | "name" => "Thụy Điển",
106 | "slug" => "thuy-dien",
107 | ],
108 | [
109 | "name" => "Malaysia",
110 | "slug" => "malaysia",
111 | ],
112 | [
113 | "name" => "Brazil",
114 | "slug" => "brazil",
115 | ],
116 | [
117 | "name" => "Philippines",
118 | "slug" => "philippines",
119 | ],
120 | [
121 | "name" => "Bồ Đào Nha",
122 | "slug" => "bo-dao-nha",
123 | ],
124 | [
125 | "name" => "Ý",
126 | "slug" => "y",
127 | ],
128 | [
129 | "name" => "Đan Mạch",
130 | "slug" => "dan-mach",
131 | ],
132 | [
133 | "name" => "UAE",
134 | "slug" => "uae",
135 | ],
136 | [
137 | "name" => "Na Uy",
138 | "slug" => "na-uy",
139 | ],
140 | [
141 | "name" => "Thụy Sĩ",
142 | "slug" => "thuy-si",
143 | ],
144 | [
145 | "name" => "Châu Phi",
146 | "slug" => "chau-phi",
147 | ],
148 | [
149 | "name" => "Nam Phi",
150 | "slug" => "nam-phi",
151 | ],
152 | [
153 | "name" => "Ukraina",
154 | "slug" => "ukraina",
155 | ],
156 | [
157 | "name" => "Ả Rập Xê Út",
158 | "slug" => "a-rap-xe-ut",
159 | ],
160 | ];
161 |
162 | foreach ($regions as $index => $region) {
163 | $result = Region::updateOrCreate($region);
164 |
165 | if (!$result) {
166 | $this->command->info("Insert failed at record $index.");
167 |
168 | return;
169 | }
170 | }
171 |
172 | $this->command->info('Inserted ' . count($regions) . ' regions.');
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/draft.yml:
--------------------------------------------------------------------------------
1 | php artisan make:migration:schema create_categories_table --schema="name:string:unique,slug:string:unique,seo_title:string,seo_des:string,seo_key:string"
2 | php artisan make:migration:schema create_countries_table --schema="name:string:unique,slug:string:unique,seo_title:string,seo_des:string,seo_key:string"
3 | php artisan make:migration:schema create_movies_table --schema="name:string:unique,slug:string:unique,seo_title:string,seo_des:string,seo_key:string"
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "npm run development",
5 | "development": "mix",
6 | "watch": "mix watch",
7 | "watch-poll": "mix watch -- --watch-options-poll=1000",
8 | "hot": "mix watch --hot",
9 | "prod": "npm run production",
10 | "production": "mix --production"
11 | },
12 | "devDependencies": {
13 | "axios": "^0.21",
14 | "laravel-mix": "^6.0.6",
15 | "lodash": "^4.17.19",
16 | "postcss": "^8.1.14"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/resources/views/core/base/columns/relationship.blade.php:
--------------------------------------------------------------------------------
1 | @php
2 | $column['value'] = $column['value'] ?? data_get($entry, $column['name']);
3 | $column['escaped'] = $column['escaped'] ?? true;
4 | $column['text'] = $column['default'] ?? '-';
5 |
6 | if ($column['value'] instanceof \Closure) {
7 | $column['value'] = $column['value']($entry);
8 | }
9 |
10 | if (!empty($column['value'])) {
11 | $column['text'] = isset($column['value']->name) ? $column['value']->name : $column['value']->pluck('name')->implode(', ');
12 | }
13 | @endphp
14 |
15 |
16 | @includeWhen(!empty($column['wrapper']), 'crud::columns.inc.wrapper_start')
17 | @if ($column['escaped'])
18 | {{ $column['text'] }}
19 | @else
20 | {!! $column['text'] !!}
21 | @endif
22 | @includeWhen(!empty($column['wrapper']), 'crud::columns.inc.wrapper_end')
23 |
24 |
--------------------------------------------------------------------------------
/resources/views/core/base/fields/checklist.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @php
3 | $key_attribute = (new $field['model']())->getKeyName();
4 | $field['attribute'] = $field['attribute'] ?? (new $field['model']())->identifiableAttribute();
5 | $field['number_of_columns'] = $field['number_of_columns'] ?? 3;
6 |
7 | // calculate the checklist options
8 | if (!isset($field['options'])) {
9 | $field['options'] = $field['model']
10 | ::all()
11 | ->pluck($field['attribute'], $key_attribute)
12 | ->toArray();
13 | } else {
14 | $field['options'] = call_user_func($field['options'], $field['model']::query());
15 | }
16 |
17 | // calculate the value of the hidden input
18 | $field['value'] = old_empty_or_null($field['name'], []) ?? ($field['value'] ?? ($field['default'] ?? []));
19 | if (!empty($field['value'])) {
20 | if (is_a($field['value'], \Illuminate\Support\Collection::class)) {
21 | $field['value'] = $field['value']->pluck($key_attribute)->toArray();
22 | } elseif (is_string($field['value'])) {
23 | $field['value'] = json_decode($field['value']);
24 | }
25 | }
26 |
27 | // define the init-function on the wrapper
28 | $field['wrapper']['data-init-function'] = $field['wrapper']['data-init-function'] ?? 'bpFieldInitChecklist';
29 | @endphp
30 |
31 | @include('crud::fields.inc.wrapper_start')
32 |
33 | @include('crud::fields.inc.translatable_icon')
34 |
35 |
36 |
37 |
38 | @foreach ($field['options'] as $key => $option)
39 |
40 |
41 |
44 |
45 |
46 | @endforeach
47 |
48 |
49 | {{-- HINT --}}
50 | @if (isset($field['hint']))
51 | {!! $field['hint'] !!}
52 | @endif
53 | @include('crud::fields.inc.wrapper_end')
54 |
55 |
56 | {{-- ########################################## --}}
57 | {{-- Extra CSS and JS for this particular field --}}
58 | {{-- If a field type is shown multiple times on a form, the CSS and JS will only be loaded once --}}
59 | {{-- FIELD JS - will be loaded in the after_scripts section --}}
60 | @push('crud_fields_scripts')
61 | @loadOnce('bpFieldInitChecklist')
62 |
106 | @endLoadOnce
107 | @endpush
108 | {{-- End of Extra CSS and JS --}}
109 | {{-- ########################################## --}}
110 |
--------------------------------------------------------------------------------
/resources/views/core/base/fields/ckfinder.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @include('crud::fields.inc.wrapper_start')
3 | @php
4 | $field['has_preview'] = isset($field['has_preview']) ? $field['has_preview'] : false;
5 | $field['preview']['width'] = isset($field['preview']['width']) ? $field['preview']['width'] : '90%';
6 | $field['preview']['height'] = isset($field['preview']['height']) ? $field['preview']['height'] : '90%';
7 | @endphp
8 |
9 |
10 |
13 |
14 |
16 |
17 |
18 | @if ($field['has_preview'] && old($field['name'], isset($entry) ? $entry->{$field['name']} : ''))
19 |
22 | @endif
23 |
24 |
25 |
26 | {{-- HINT --}}
27 | @if (isset($field['hint']))
28 | {!! $field['hint'] !!}
29 | @endif
30 | @include('crud::fields.inc.wrapper_end')
31 |
32 | @if ($crud->fieldTypeNotLoaded($field))
33 | @php
34 | $crud->markFieldTypeAsLoaded($field);
35 | @endphp
36 |
37 | {{-- FIELD EXTRA CSS --}}
38 | {{-- push things in the after_styles section --}}
39 | @push('crud_fields_styles')
40 |
41 | @endpush
42 |
43 | {{-- FIELD EXTRA JS --}}
44 | {{-- push things in the after_scripts section --}}
45 | @push('crud_fields_scripts')
46 | @include('ckfinder::setup')
47 |
75 | @endpush
76 | @endif
77 |
--------------------------------------------------------------------------------
/resources/views/core/base/fields/fields_option.blade.php:
--------------------------------------------------------------------------------
1 | @php
2 | $value = isset($field) ? old_empty_or_null($field['name'], '') ?? ($field['value'] ?? null) : null;
3 | @endphp
4 |
5 | @php
6 | $progress = [
7 | 'episodes' => 'Tập mới',
8 | 'status' => 'Trạng thái phim',
9 | 'episode_time' => 'Thời lượng tập phim',
10 | 'episode_current' => 'Số tập phim hiện tại',
11 | 'episode_total' => 'Tổng số tập phim',
12 | ];
13 |
14 | $info = [
15 | 'name' => 'Tên phim',
16 | 'origin_name' => 'Tên gốc phim',
17 | 'content' => 'Mô tả nội dung phim',
18 | 'thumb_url' => 'Ảnh Thumb',
19 | 'poster_url' => 'Ảnh Poster',
20 | 'trailer_url' => 'Trailer URL',
21 | 'quality' => 'Chất lượng phim',
22 | 'language' => 'Ngôn ngữ',
23 | 'notify' => 'Nội dung thông báo',
24 | 'showtimes' => 'Giờ chiếu phim',
25 | 'publish_year' => 'Năm xuất bản',
26 | 'is_shown_in_theater' => 'Đánh dấu phim chiếu rạp',
27 | 'is_copyright' => 'Đánh dấu có bản quyền',
28 | ];
29 |
30 | $relations = [
31 | 'type' => 'Định dạng phim',
32 | 'actors' => 'Diễn viên',
33 | 'directors' => 'Đạo diễn',
34 | 'categories' => 'Thể loại',
35 | 'regions' => 'Khu vực',
36 | 'tags' => 'Từ khóa',
37 | 'studios' => 'Studio',
38 | ];
39 | @endphp
40 |
41 |
83 |
84 | {{-- FIELD JS - will be loaded in the after_scripts section --}}
85 | @push('crud_fields_scripts')
86 |
91 | @endpush
92 |
--------------------------------------------------------------------------------
/resources/views/core/base/fields/select2_from_array.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @include('crud::fields.inc.wrapper_start')
3 | @php
4 | $field['allows_multiple'] = $field['allows_multiple'] ?? false;
5 | $field['options'] = $field['options'] ?? [];
6 | $field['value'] = $field['value'] ?? [];
7 |
8 | @endphp
9 |
10 |
17 |
18 | {{-- HINT --}}
19 | @if (isset($field['hint']))
20 | {!! $field['hint'] !!}
21 | @endif
22 | @include('crud::fields.inc.wrapper_end')
23 |
24 | @if ($crud->fieldTypeNotLoaded($field))
25 | @php
26 | $crud->markFieldTypeAsLoaded($field);
27 | @endphp
28 |
29 | {{-- FIELD EXTRA CSS --}}
30 | {{-- push things in the after_styles section --}}
31 | @push('crud_fields_styles')
32 |
33 | @endpush
34 |
35 | {{-- FIELD EXTRA JS --}}
36 | {{-- push things in the after_scripts section --}}
37 | @push('crud_fields_scripts')
38 |
43 | @endpush
44 | @endif
45 |
--------------------------------------------------------------------------------
/resources/views/core/base/fields/select2_relationship_tags.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @include('crud::fields.inc.wrapper_start')
3 | @php
4 | $key_attribute = (new $field['model']())->getKeyName();
5 | $field['attribute'] = $field['attribute'] ?? (new $field['model']())->identifiableAttribute();
6 |
7 | $selected = $field['model']
8 | ::whereIn('id', old($field['name'], isset($field['value']) ? $field['value']->pluck('id')->toArray() : []))
9 | ->pluck($field['attribute'], $key_attribute)
10 | ->toArray();
11 | @endphp
12 |
13 |
19 |
20 | {{-- HINT --}}
21 | @if (isset($field['hint']))
22 | {!! $field['hint'] !!}
23 | @endif
24 | @include('crud::fields.inc.wrapper_end')
25 |
26 | @if ($crud->fieldTypeNotLoaded($field))
27 | @php
28 | $crud->markFieldTypeAsLoaded($field);
29 | @endphp
30 |
31 | {{-- FIELD EXTRA CSS --}}
32 | {{-- push things in the after_styles section --}}
33 | @push('crud_fields_styles')
34 |
35 | @endpush
36 |
37 | {{-- FIELD EXTRA JS --}}
38 | {{-- push things in the after_scripts section --}}
39 | @push('crud_fields_scripts')
40 |
47 | @endpush
48 | @endif
49 |
--------------------------------------------------------------------------------
/resources/views/core/base/fields/select2_tags.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @include('crud::fields.inc.wrapper_start')
3 |
4 | @php
5 | $selected = $field['value'] ?? [];
6 | @endphp
7 |
8 |
9 |
15 |
16 | {{-- HINT --}}
17 | @if (isset($field['hint']))
18 | {!! $field['hint'] !!}
19 | @endif
20 | @include('crud::fields.inc.wrapper_end')
21 |
22 | @if ($crud->fieldTypeNotLoaded($field))
23 | @php
24 | $crud->markFieldTypeAsLoaded($field);
25 | @endphp
26 |
27 | {{-- FIELD EXTRA CSS --}}
28 | {{-- push things in the after_styles section --}}
29 | @push('crud_fields_styles')
30 |
31 | @endpush
32 |
33 | {{-- FIELD EXTRA JS --}}
34 | {{-- push things in the after_scripts section --}}
35 | @push('crud_fields_scripts')
36 |
43 | @endpush
44 | @endif
45 |
--------------------------------------------------------------------------------
/resources/views/core/base/fields/select_from_table.blade.php:
--------------------------------------------------------------------------------
1 | @php
2 | $field['allows_null'] = $field['allows_null'] ?? $crud->model::isColumnNullable($field['name']);
3 | $field['value'] = old_empty_or_null($field['name'], '') ?? ($field['value'] ?? ($field['default'] ?? ''));
4 | $field['multiple'] = $field['allows_multiple'] ?? ($field['multiple'] ?? false);
5 | $field['options']['display_by'] = isset($field['options']['display_by']) ? $field['options']['display_by'] : 'name';
6 | $field['options']['value_by'] = isset($field['options']['value_by']) ? $field['options']['value_by'] : 'id';
7 | $options = \DB::table($field['options']['table'])
8 | ->pluck($field['options']['display_by'], $field['options']['value_by'])
9 | ->toArray();
10 | @endphp
11 |
12 | @include('crud::fields.inc.wrapper_start')
13 |
14 | @include('crud::fields.inc.translatable_icon')
15 | @if ($field['multiple'])
16 |
17 | @endif
18 |
19 |
35 |
36 | {{-- HINT --}}
37 | @if (isset($field['hint']))
38 | {!! $field['hint'] !!}
39 | @endif
40 | @include('crud::fields.inc.wrapper_end')
41 |
--------------------------------------------------------------------------------
/resources/views/core/base/fields/select_theme.blade.php:
--------------------------------------------------------------------------------
1 | @php
2 | $field['value'] = old_empty_or_null($field['name'], '') ?? ($field['value'] ?? ($field['default'] ?? ''));
3 | $field['multiple'] = $field['allows_multiple'] ?? ($field['multiple'] ?? false);
4 | $options = config('themes', []);
5 | @endphp
6 |
7 | @include('crud::fields.inc.wrapper_start')
8 |
9 | @include('crud::fields.inc.translatable_icon')
10 | @if ($field['multiple'])
11 |
12 | @endif
13 |
14 |
25 |
26 | {{-- HINT --}}
27 | @if (isset($field['hint']))
28 | {!! $field['hint'] !!}
29 | @endif
30 | @include('crud::fields.inc.wrapper_end')
31 |
--------------------------------------------------------------------------------
/resources/views/core/base/fields/update_fields_option.blade.php:
--------------------------------------------------------------------------------
1 | @php
2 | $value = isset($field) ? old_empty_or_null($field['name'], '') ?? ($field['value'] ?? null) : null;
3 | @endphp
4 |
5 | @php
6 | $progress = [
7 | 'episodes' => 'Tập mới',
8 | 'status' => 'Trạng thái phim',
9 | 'episode_time' => 'Thời lượng tập phim',
10 | 'episode_current' => 'Số tập phim hiện tại',
11 | 'episode_total' => 'Tổng số tập phim',
12 | ];
13 |
14 | $info = [
15 | 'name' => 'Tên phim',
16 | 'origin_name' => 'Tên gốc phim',
17 | 'content' => 'Mô tả nội dung phim',
18 | 'thumb_url' => 'Ảnh Thumb',
19 | 'poster_url' => 'Ảnh Poster',
20 | 'trailer_url' => 'Trailer URL',
21 | 'quality' => 'Chất lượng phim',
22 | 'language' => 'Ngôn ngữ',
23 | 'notify' => 'Nội dung thông báo',
24 | 'showtimes' => 'Giờ chiếu phim',
25 | 'publish_year' => 'Năm xuất bản',
26 | 'is_shown_in_theater' => 'Đánh dấu phim chiếu rạp',
27 | 'is_copyright' => 'Đánh dấu có bản quyền',
28 | ];
29 |
30 | $relations = [
31 | 'type' => 'Định dạng phim',
32 | 'actors' => 'Diễn viên',
33 | 'directors' => 'Đạo diễn',
34 | 'categories' => 'Thể loại',
35 | 'regions' => 'Khu vực',
36 | 'tags' => 'Từ khóa',
37 | 'studios' => 'Studio',
38 | ];
39 | @endphp
40 |
41 |
83 |
84 | {{-- FIELD JS - will be loaded in the after_scripts section --}}
85 | @push('after_scripts')
86 |
91 | @endpush
92 |
--------------------------------------------------------------------------------
/resources/views/core/base/inc/main_header.blade.php:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/resources/views/core/base/inc/topbar_right_content.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
13 |
14 |
--------------------------------------------------------------------------------
/resources/views/core/crud/buttons/bulk_delete.blade.php:
--------------------------------------------------------------------------------
1 | @if ($crud->hasAccess('bulkDelete') && $crud->get('list.bulkActions'))
2 | {{ trans('backpack::crud.delete') }}
3 | @endif
4 |
5 | @push('after_scripts')
6 |
104 | @endpush
105 |
--------------------------------------------------------------------------------
/resources/views/core/crud/filters/select2.blade.php:
--------------------------------------------------------------------------------
1 | {{-- Select2 Backpack CRUD filter --}}
2 |
6 | {{ $filter->label }}
7 |
34 |
35 |
36 | {{-- ########################################### --}}
37 | {{-- Extra CSS and JS for this particular filter --}}
38 |
39 | {{-- FILTERS EXTRA CSS --}}
40 | {{-- push things in the after_styles section --}}
41 |
42 | @push('crud_list_styles')
43 | {{-- include select2 css --}}
44 |
45 |
46 |
69 | @endpush
70 |
71 |
72 | {{-- FILTERS EXTRA JS --}}
73 | {{-- push things in the after_scripts section --}}
74 |
75 | @push('crud_list_scripts')
76 | {{-- include select2 js --}}
77 |
78 | @if (app()->getLocale() !== 'en')
79 |
80 | @endif
81 |
82 |
138 | @endpush
139 | {{-- End of Extra CSS and JS --}}
140 | {{-- ########################################## --}}
141 |
--------------------------------------------------------------------------------
/resources/views/core/crud/filters/simple.blade.php:
--------------------------------------------------------------------------------
1 | {{-- Simple Backpack CRUD filter --}}
2 |
6 | {{ $filter->label }}
9 |
10 |
11 |
12 | {{-- ########################################### --}}
13 | {{-- Extra CSS and JS for this particular filter --}}
14 |
15 | {{-- FILTERS EXTRA CSS --}}
16 | {{-- push things in the after_styles section --}}
17 |
18 | {{-- @push('crud_list_styles')
19 | no css
20 | @endpush --}}
21 |
22 |
23 | {{-- FILTERS EXTRA JS --}}
24 | {{-- push things in the after_scripts section --}}
25 |
26 | @push('crud_list_scripts')
27 |
70 | @endpush
71 | {{-- End of Extra CSS and JS --}}
72 | {{-- ########################################## --}}
73 |
--------------------------------------------------------------------------------
/resources/views/core/movies/columns/column_movie_info.blade.php:
--------------------------------------------------------------------------------
1 | @php
2 | $name = data_get($entry, $column['name']);
3 | $origin_name = data_get($entry, $column['origin_name']);
4 | $publish_year = data_get($entry, $column['publish_year']);
5 | $episode_current = data_get($entry, $column['episode_current']);
6 | $status = data_get($entry, $column['status']);
7 | $movie_type = data_get($entry, $column['movie_type']);
8 | $config_show_type = [
9 | 'single' => [
10 | 'class' => 'bg-secondary',
11 | 'label' => 'Phim lẻ',
12 | ],
13 | 'series' => [
14 | 'class' => 'bg-primary',
15 | 'label' => 'Phim bộ',
16 | ],
17 | ];
18 | $config_show_status = [
19 | 'trailer' => [
20 | 'class' => 'bg-warning',
21 | 'label' => 'Trailer',
22 | ],
23 | 'ongoing' => [
24 | 'class' => 'bg-info',
25 | 'label' => 'Đang chiếu',
26 | ],
27 | 'completed' => [
28 | 'class' => 'bg-success',
29 | 'label' => 'Hoàn thành',
30 | ],
31 | ];
32 | @endphp
33 |
34 | @includeWhen(!empty($column['wrapper']), 'crud::columns.inc.wrapper_start')
35 |
{{ $name }} [{{ $publish_year }}]
36 |
({{ $origin_name }}) [{{ $episode_current }}]
37 |
{{ $config_show_type[$movie_type]['label'] }}
38 |
{{ $config_show_status[$status]['label'] }}
39 | @includeWhen(!empty($column['wrapper']), 'crud::columns.inc.wrapper_end')
40 |
41 |
--------------------------------------------------------------------------------
/resources/views/core/movies/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends(backpack_view('blank'))
2 |
3 | @php
4 | $defaultBreadcrumbs = [
5 | trans('backpack::crud.admin') => url(config('backpack.base.route_prefix'), 'dashboard'),
6 | $crud->entity_name_plural => url($crud->route),
7 | trans('backpack::crud.add') => false,
8 | ];
9 |
10 | // if breadcrumbs aren't defined in the CrudController, use the default breadcrumbs
11 | $breadcrumbs = $breadcrumbs ?? $defaultBreadcrumbs;
12 | @endphp
13 |
14 | @section('header')
15 |
28 | @endsection
29 |
30 | @section('content')
31 |
32 |
33 |
34 |
35 | @include('crud::inc.grouped_errors')
36 |
37 |
54 |
55 |
56 | @endsection
57 |
--------------------------------------------------------------------------------
/resources/views/core/movies/edit.blade.php:
--------------------------------------------------------------------------------
1 | @extends(backpack_view('blank'))
2 |
3 | @php
4 | $defaultBreadcrumbs = [
5 | trans('backpack::crud.admin') => backpack_url('dashboard'),
6 | $crud->entity_name_plural => url($crud->route),
7 | trans('backpack::crud.edit') => false,
8 | ];
9 |
10 | // if breadcrumbs aren't defined in the CrudController, use the default breadcrumbs
11 | $breadcrumbs = $breadcrumbs ?? $defaultBreadcrumbs;
12 | @endphp
13 |
14 | @section('header')
15 |
25 | @endsection
26 |
27 | @section('content')
28 |
29 |
30 |
31 |
32 | @include('crud::inc.grouped_errors')
33 |
34 |
68 |
69 |
70 | @endsection
71 |
72 |
--------------------------------------------------------------------------------
/resources/views/themes/layout.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {!! setting('site_meta_head_tags', '') !!}
6 |
7 |
8 |
9 |
10 | {!! SEO::generate() !!}
11 | @stack('header')
12 | {!! get_theme_option('additional_css') !!}
13 | {!! get_theme_option('additional_header_js') !!}
14 |
15 |
16 |
17 | @yield('body')
18 | {!! get_theme_option('additional_body_js') !!}
19 |
20 | @yield('footer')
21 | @stack('scripts')
22 | {!! get_theme_option('additional_footer_js') !!}
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/routes/admin.php:
--------------------------------------------------------------------------------
1 | config('backpack.base.route_prefix', 'admin'),
14 | 'middleware' => array_merge(
15 | (array) config('backpack.base.web_middleware', 'web'),
16 | (array) config('backpack.base.middleware_key', 'admin')
17 | ),
18 | 'namespace' => 'Ophim\Core\Controllers\Admin',
19 | ], function () {
20 | if (config('backpack.base.setup_dashboard_routes')) {
21 | Route::get('dashboard', 'AdminController@dashboard')->name('backpack.dashboard');
22 | Route::get('/', 'AdminController@redirect')->name('backpack');
23 | }
24 |
25 | Route::crud('catalog', 'CatalogCrudController');
26 | Route::crud('category', 'CategoryCrudController');
27 | Route::crud('region', 'RegionCrudController');
28 | Route::crud('movie', 'MovieCrudController');
29 | Route::crud('actor', 'ActorCrudController');
30 | Route::crud('director', 'DirectorCrudController');
31 | Route::crud('studio', 'StudioCrudController');
32 | Route::crud('tag', 'TagCrudController');
33 | Route::crud('menu', 'MenuCrudController');
34 | Route::crud('episode', 'EpisodeCrudController');
35 | Route::crud('theme', 'ThemeManagementController');
36 | Route::crud('sitemap', 'SiteMapController');
37 | Route::get('quick-action/delete-cache', 'QuickActionController@delete_cache');
38 | });
39 |
40 | Route::group([
41 | 'prefix' => config('backpack.base.route_prefix', 'admin'),
42 | 'middleware' => array_merge(
43 | [
44 | \Ophim\Core\Middleware\EncryptCookies::class,
45 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
46 | \Illuminate\Session\Middleware\StartSession::class,
47 | \Illuminate\View\Middleware\ShareErrorsFromSession::class,
48 | \Illuminate\Routing\Middleware\SubstituteBindings::class
49 | ],
50 | (array) config('backpack.base.middleware_key', 'admin')
51 | ),
52 | ], function () {
53 | Route::prefix('/ckfinder')->group(function () {
54 | Route::any('/connector', [CKFinderController::class, 'requestAction'])->name('ckfinder_connector');
55 | Route::any('/browser', [CKFinderController::class, 'browserAction'])->name('ckfinder_browser');
56 | });
57 | });
58 |
--------------------------------------------------------------------------------
/src/Console/ChangeDomainEpisodeCommand.php:
--------------------------------------------------------------------------------
1 | ['vie.opstream1.com', 'vie.haiphim.com'],
47 | 'vip.opstream15.com' => ['hd.1080phim.com', 'hd1080.opstream2.com'],
48 | 'vip.opstream14.com' => ['kd.hd-bophim.com', 'kd.opstream3.com'],
49 | 'vip.opstream11.com' => ['1080.hdphimonline.com', '1080.opstream4.com'],
50 | 'vip.opstream16.com' => ['hd.hdbophim.com', 'hdbo.opstream5.com'],
51 | 'vip.opstream12.com' => ['aa.nguonphimmoi.com', 'aa.opstream6.com'],
52 | 'vip.opstream13.com' => ['vie2.opstream7.com'],
53 | 'vip.opstream17.com' => ['vip.opstream8.com'],
54 | );
55 | foreach ($domains as $newDomain => $arrOldDomain) {
56 | foreach ($arrOldDomain as $oldDomain) {
57 | $this->info("Replace: $oldDomain => $newDomain");
58 | Episode::where('link', 'LIKE', '%' . $oldDomain . '%')->update(['link' => DB::raw("REPLACE(link, '$oldDomain', '$newDomain')")]);
59 | }
60 | }
61 |
62 | $this->info("Replace Done!");
63 | return 0;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Console/CreateUser.php:
--------------------------------------------------------------------------------
1 | info('Creating a new user');
36 |
37 | if (!$name = $this->option('name')) {
38 | $name = $this->ask('Name');
39 | }
40 |
41 | if (!$email = $this->option('email')) {
42 | $email = $this->ask('Email');
43 | }
44 |
45 | if (!$password = $this->option('password')) {
46 | $password = $this->secret('Password');
47 | }
48 |
49 | if (!$this->confirm('Is administrator? [y|N]', $isAdmin = false)) {
50 | $isAdmin = false;
51 | } else {
52 | $isAdmin = true;
53 | }
54 |
55 | if ($this->option('encrypt')) {
56 | $password = bcrypt($password);
57 | }
58 |
59 | $auth = config('backpack.base.user_model_fqn', 'App\User');
60 | $user = new $auth();
61 | $user->name = $name;
62 | $user->email = $email;
63 | $user->password = $password;
64 |
65 | if ($user->save()) {
66 | $this->info('Successfully created new user');
67 | if ($isAdmin) {
68 | $user->roles()->attach(Role::firstOrCreate(['name' => 'Admin', 'guard_name' => 'backpack']));
69 | }
70 | } else {
71 | $this->error('Something went wrong trying to save your user');
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Console/GenerateMenuCommand.php:
--------------------------------------------------------------------------------
1 | call('db:seed', [
45 | 'class' => MenusTableSeeder::class,
46 | ]);
47 | $this->info('Menu is generated.');
48 |
49 | return 0;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Console/InstallCommand.php:
--------------------------------------------------------------------------------
1 | progressBar = $this->output->createProgressBar(18);
53 | $this->progressBar->minSecondsBetweenRedraws(0);
54 | $this->progressBar->maxSecondsBetweenRedraws(120);
55 | $this->progressBar->setRedrawFrequency(1);
56 |
57 | $this->progressBar->start();
58 |
59 | $this->call('vendor:publish', [
60 | '--provider' => 'Backpack\CRUD\BackpackServiceProvider',
61 | '--tag' => 'config',
62 | ]);
63 | $this->progressBar->advance();
64 | $this->newLine(1);
65 |
66 | $this->call('vendor:publish', [
67 | '--provider' => 'Backpack\CRUD\BackpackServiceProvider',
68 | '--tag' => 'config',
69 | ]);
70 | $this->progressBar->advance();
71 | $this->newLine(1);
72 |
73 | $this->call('vendor:publish', [
74 | '--provider' => 'Backpack\CRUD\BackpackServiceProvider',
75 | '--tag' => 'public',
76 | ]);
77 | $this->progressBar->advance();
78 | $this->newLine(1);
79 |
80 | $this->call('vendor:publish', [
81 | '--provider' => 'Backpack\CRUD\BackpackServiceProvider',
82 | '--tag' => 'gravatar',
83 | ]);
84 | $this->progressBar->advance();
85 | $this->newLine(1);
86 |
87 |
88 | $this->call('migrate', $this->option('no-interaction') ? ['--no-interaction' => true] : []);
89 | $this->progressBar->advance();
90 | $this->newLine(1);
91 |
92 | $this->call('backpack:publish-middleware');
93 | $this->progressBar->advance();
94 | $this->newLine(1);
95 |
96 | $this->call('vendor:publish', [
97 | '--tag' => 'cms_menu_content',
98 | '--force' => true
99 | ]);
100 | $this->progressBar->advance();
101 | $this->newLine(1);
102 |
103 | $this->call('vendor:publish', [
104 | '--tag' => 'players',
105 | ]);
106 | $this->progressBar->advance();
107 | $this->newLine(1);
108 |
109 | $this->installCKfinder();
110 | $this->progressBar->advance();
111 | $this->newLine(1);
112 |
113 | $this->call('db:seed', [
114 | 'class' => SettingsTableSeeder::class,
115 | ]);
116 | $this->progressBar->advance();
117 | $this->newLine(1);
118 |
119 | $this->call('db:seed', [
120 | 'class' => CatalogsTableSeeder::class,
121 | ]);
122 | $this->progressBar->advance();
123 | $this->newLine(1);
124 |
125 | $this->call('db:seed', [
126 | 'class' => MenusTableSeeder::class,
127 | ]);
128 | $this->progressBar->advance();
129 | $this->newLine(1);
130 |
131 | $this->call('db:seed', [
132 | 'class' => PermissionsSeeder::class,
133 | ]);
134 | $this->progressBar->advance();
135 | $this->newLine(1);
136 |
137 | $this->progressBar->finish();
138 | $this->newLine(1);
139 | $this->info('Ophim installation finished.');
140 |
141 | return 0;
142 | }
143 |
144 | protected function installCKfinder()
145 | {
146 | $this->call('ckfinder:download');
147 | $this->call('vendor:publish', [
148 | '--tag' => 'ckfinder-assets',
149 | ]);
150 | $this->progressBar->advance();
151 | $this->newLine(1);
152 |
153 | $this->call('vendor:publish', [
154 | '--tag' => 'ckfinder-config',
155 | ]);
156 |
157 | $this->call('storage:link');
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/Contracts/HasUrlInterface.php:
--------------------------------------------------------------------------------
1 | authorize('browse', Actor::class);
44 |
45 | CRUD::addColumn(['name' => 'name', 'label' => 'Tên', 'type' => 'text']);
46 | CRUD::addColumn(['name' => 'slug', 'label' => 'Đường dẫn tĩnh', 'type' => 'text']);
47 | CRUD::addColumn(['name' => 'gender', 'label' => 'Giới tính', 'type' => 'text']);
48 | CRUD::addColumn(['name' => 'image', 'label' => 'Ảnh', 'type' => 'image']);
49 | }
50 |
51 | /**
52 | * Define what happens when the Create operation is loaded.
53 | *
54 | * @see https://backpackforlaravel.com/docs/crud-operation-create
55 | * @return void
56 | */
57 | protected function setupCreateOperation()
58 | {
59 | $this->authorize('create', Actor::class);
60 |
61 | CRUD::setValidation(ActorRequest::class);
62 |
63 | CRUD::addField(['name' => 'name', 'label' => 'Tên', 'type' => 'text']);
64 | CRUD::addField(['name' => 'slug', 'label' => 'Đường dẫn tĩnh', 'type' => 'text']);
65 | CRUD::addField(['name' => 'image', 'label' => 'Ảnh', 'type' => 'upload']);
66 | CRUD::addField([
67 | 'name' => 'gender',
68 | 'label' => "Giới tính",
69 | 'type' => 'select_from_array',
70 | 'options' => ['male' => 'Nam', 'female' => 'Nữ', 'other' => 'Khác'],
71 | 'allows_null' => false,
72 | 'default' => 'one',
73 | ],);
74 | }
75 |
76 | /**
77 | * Define what happens when the Update operation is loaded.
78 | *
79 | * @see https://backpackforlaravel.com/docs/crud-operation-update
80 | * @return void
81 | */
82 | protected function setupUpdateOperation()
83 | {
84 | $this->authorize('update', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
85 |
86 | $this->setupCreateOperation();
87 | }
88 |
89 | protected function setupDeleteOperation()
90 | {
91 | $this->authorize('delete', $this->crud->model);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/AdminController.php:
--------------------------------------------------------------------------------
1 | middleware(backpack_middleware());
21 | }
22 |
23 | /**
24 | * Show the admin dashboard.
25 | *
26 | * @return \Illuminate\Http\Response
27 | */
28 | public function dashboard()
29 | {
30 | $this->data['title'] = trans('backpack::base.dashboard'); // set the page title
31 | $this->data['breadcrumbs'] = [
32 | trans('backpack::crud.admin') => backpack_url('dashboard'),
33 | trans('backpack::base.dashboard') => false,
34 | ];
35 | $this->data['count_movies'] = Movie::count();
36 | $this->data['count_episodes'] = Episode::count();
37 | $this->data['count_episodes_error'] = Episode::where('has_report', true)->count();
38 | $this->data['count_themes'] = Theme::count();
39 | $this->data['count_users'] = User::count();
40 | $this->data['top_view_day'] = Movie::orderBy('view_day', 'desc')->limit(15)->get();
41 | $this->data['top_view_week'] = Movie::orderBy('view_week', 'desc')->limit(15)->get();
42 | $this->data['top_view_month'] = Movie::orderBy('view_month', 'desc')->limit(15)->get();
43 | return view(backpack_view('dashboard'), $this->data);
44 | }
45 |
46 | /**
47 | * Redirect to the dashboard.
48 | *
49 | * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
50 | */
51 | public function redirect()
52 | {
53 | // The '/admin' route is not to be used as a page, because it breaks the menu's active state.
54 | return redirect(backpack_url('dashboard'));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/CatalogCrudController.php:
--------------------------------------------------------------------------------
1 | authorize('browse', Catalog::class);
44 |
45 | CRUD::addButtonFromModelFunction('line', 'open_view', 'openView', 'beginning');
46 |
47 | CRUD::column('name')->label('Tên')->type('text');
48 | CRUD::column('slug')->label('Đường dẫn tĩnh')->type('text');
49 | CRUD::column('paginate')->label('Item per page')->type('number');
50 | CRUD::column('value')->label('Value')->type('text');
51 | CRUD::column('seo_title')->label('SEO Title')->type('text');
52 | CRUD::column('seo_des')->label('SEO Description')->type('text');
53 | CRUD::column('seo_key')->label('SEO Keyword')->type('text');
54 | }
55 |
56 | /**
57 | * Define what happens when the Create operation is loaded.
58 | *
59 | * @see https://backpackforlaravel.com/docs/crud-operation-create
60 | * @return void
61 | */
62 | protected function setupCreateOperation()
63 | {
64 | $this->authorize('create', Catalog::class);
65 |
66 | CRUD::setValidation(CatalogRequest::class);
67 |
68 | CRUD::field('name')->label('Tên')->type('text');
69 | CRUD::field('slug')->label('Đường dẫn tĩnh')->type('text');
70 | CRUD::field('paginate')->label('Paginate')->hint('Item per page')->type('number');
71 | CRUD::field('value')->label('Value')->hint('relation_tables,relation_field,relation_value|find_by_field_1,find_by_fiel_2,...,find_by_field_n|value_1,value_2,...,value_n|sort_by_field|sort_algo')->type('text');
72 | CRUD::field('seo_title')->label('SEO Title')->type('text');
73 | CRUD::field('seo_des')->label('SEO Description')->type('textarea');
74 | CRUD::field('seo_key')->label('SEO Keyword')->type('text');
75 | }
76 |
77 | /**
78 | * Define what happens when the Update operation is loaded.
79 | *
80 | * @see https://backpackforlaravel.com/docs/crud-operation-update
81 | * @return void
82 | */
83 | protected function setupUpdateOperation()
84 | {
85 | $this->authorize('update', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
86 |
87 | $this->setupCreateOperation();
88 | }
89 |
90 | protected function setupDeleteOperation()
91 | {
92 | $this->authorize('delete', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/CategoryCrudController.php:
--------------------------------------------------------------------------------
1 | authorize('browse', Category::class);
44 |
45 | CRUD::column('name')->label('Tên')->type('text');
46 | CRUD::column('slug')->label('Đường dẫn tĩnh')->type('text');
47 | CRUD::column('seo_title')->label('SEO Title')->type('text');
48 | CRUD::column('seo_des')->label('SEO Description')->type('text');
49 | CRUD::column('seo_key')->label('SEO Keyword')->type('text');
50 | }
51 |
52 | /**
53 | * Define what happens when the Create operation is loaded.
54 | *
55 | * @see https://backpackforlaravel.com/docs/crud-operation-create
56 | * @return void
57 | */
58 | protected function setupCreateOperation()
59 | {
60 | $this->authorize('create', Category::class);
61 |
62 | CRUD::setValidation(CategoryRequest::class);
63 |
64 | CRUD::field('name')->label('Tên')->type('text');
65 | CRUD::field('slug')->label('Đường dẫn tĩnh')->type('text');
66 | CRUD::field('seo_title')->label('SEO Title')->type('text');
67 | CRUD::field('seo_des')->label('SEO Description')->type('textarea');
68 | CRUD::field('seo_key')->label('SEO Keyword')->type('text');
69 | }
70 |
71 | /**
72 | * Define what happens when the Update operation is loaded.
73 | *
74 | * @see https://backpackforlaravel.com/docs/crud-operation-update
75 | * @return void
76 | */
77 | protected function setupUpdateOperation()
78 | {
79 | $this->authorize('update', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
80 |
81 |
82 | $this->setupCreateOperation();
83 | }
84 |
85 | protected function setupDeleteOperation()
86 | {
87 | $this->authorize('delete', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/DirectorCrudController.php:
--------------------------------------------------------------------------------
1 | authorize('browse', Director::class);
44 |
45 | /**
46 | * Columns can be defined using the fluent syntax or array syntax:
47 | * - CRUD::column('price')->type('number');
48 | * - CRUD::addColumn(['name' => 'price', 'type' => 'number']);
49 | */
50 |
51 |
52 | CRUD::addColumn(['name' => 'name', 'label' => 'Tên', 'type' => 'text']);
53 | CRUD::addColumn(['name' => 'slug', 'label' => 'Đường dẫn tĩnh', 'type' => 'text']);
54 | CRUD::addColumn(['name' => 'gender', 'label' => 'Giới tính', 'type' => 'text']);
55 | CRUD::addColumn(['name' => 'image', 'label' => 'Ảnh', 'type' => 'image']);
56 | }
57 |
58 | /**
59 | * Define what happens when the Create operation is loaded.
60 | *
61 | * @see https://backpackforlaravel.com/docs/crud-operation-create
62 | * @return void
63 | */
64 | protected function setupCreateOperation()
65 | {
66 | $this->authorize('create', Director::class);
67 |
68 | CRUD::setValidation(DirectorRequest::class);
69 |
70 | /**
71 | * Fields can be defined using the fluent syntax or array syntax:
72 | * - CRUD::field('price')->type('number');
73 | * - CRUD::addField(['name' => 'price', 'type' => 'number']));
74 | */
75 |
76 | CRUD::addField(['name' => 'name', 'label' => 'Tên', 'type' => 'text']);
77 | CRUD::addField(['name' => 'slug', 'label' => 'Đường dẫn tĩnh', 'type' => 'text']);
78 | CRUD::addField(['name' => 'image', 'label' => 'Ảnh', 'type' => 'upload']);
79 | CRUD::addField([
80 | 'name' => 'gender',
81 | 'label' => "Giới tính",
82 | 'type' => 'select_from_array',
83 | 'options' => ['male' => 'Nam', 'female' => 'Nữ', 'other' => 'Khác'],
84 | 'allows_null' => false,
85 | 'default' => 'one',
86 | ],);
87 | }
88 |
89 | /**
90 | * Define what happens when the Update operation is loaded.
91 | *
92 | * @see https://backpackforlaravel.com/docs/crud-operation-update
93 | * @return void
94 | */
95 | protected function setupUpdateOperation()
96 | {
97 | $this->authorize('update', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
98 |
99 |
100 | $this->setupCreateOperation();
101 | }
102 |
103 | protected function setupDeleteOperation()
104 | {
105 | $this->authorize('delete', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/EpisodeCrudController.php:
--------------------------------------------------------------------------------
1 | crud->addButtonFromModelFunction('line', 'open_episode', 'openEpisode', 'beginning');
42 | $this->crud->denyAccess('create');
43 | $this->crud->denyAccess('delete');
44 | }
45 |
46 | /**
47 | * Define what happens when the List operation is loaded.
48 | *
49 | * @see https://backpackforlaravel.com/docs/crud-operation-list-entries
50 | * @return void
51 | */
52 | protected function setupListOperation()
53 | {
54 | $this->authorize('browse', Episode::class);
55 |
56 | /**
57 | * Columns can be defined using the fluent syntax or array syntax:
58 | * - CRUD::column('price')->type('number');
59 | * - CRUD::addColumn(['name' => 'price', 'type' => 'number','tab'=>'Thông tin phim']);
60 | */
61 | $this->crud->enableExportButtons();
62 | $this->crud->addClause('where', 'has_report', true);
63 |
64 | CRUD::addColumn([
65 | 'name' => 'movie', 'label' => 'Phim', 'type' => 'relationship',
66 | 'searchLogic' => function ($query, $column, $searchTerm) {
67 | $query->orWhereHas('movie', function ($movie) use ($searchTerm) {
68 | $movie->where('name', 'like', '%' . $searchTerm . '%')
69 | ->orWhere('origin_name', 'like', '%' . $searchTerm . '%');
70 | });
71 | }
72 | ]);
73 | CRUD::addColumn(['name' => 'name', 'label' => 'Tập', 'type' => 'text']);
74 | CRUD::addColumn(['name' => 'type', 'label' => 'Type', 'type' => 'text']);
75 | CRUD::addColumn(['name' => 'link', 'label' => 'Link', 'type' => 'textarea']);
76 | }
77 |
78 | /**
79 | * Define what happens when the Create operation is loaded.
80 | *
81 | * @see https://backpackforlaravel.com/docs/crud-operation-create
82 | * @return void
83 | */
84 | protected function setupCreateOperation()
85 | {
86 | abort(404);
87 | }
88 |
89 | /**
90 | * Define what happens when the Update operation is loaded.
91 | *
92 | * @see https://backpackforlaravel.com/docs/crud-operation-update
93 | * @return void
94 | */
95 | protected function setupUpdateOperation()
96 | {
97 | $this->authorize('update', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
98 |
99 |
100 | CRUD::addField(['name' => 'type', 'label' => 'Type', 'type' => 'select_from_array', 'options' => config('ophim.episodes.types')]);
101 | CRUD::addField(['name' => 'link', 'label' => 'Nguồn phát', 'type' => 'url']);
102 | CRUD::addField(['name' => 'has_report', 'label' => 'Đánh dấu đang lỗi', 'type' => 'checkbox']);
103 | CRUD::addField(['name' => 'report_message', 'label' => 'Report message', 'type' => 'textarea']);
104 | }
105 |
106 | public function bulkDelete()
107 | {
108 | $this->crud->hasAccessOrFail('bulkDelete');
109 | $entries = request()->input('entries', []);
110 | $deletedEntries = [];
111 |
112 | foreach ($entries as $key => $id) {
113 | if ($entry = $this->crud->model->find($id)) {
114 | $deletedEntries[] = $entry->update(['has_report' => 0, 'report_message' => '']);
115 | }
116 | }
117 |
118 | return $deletedEntries;
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/MenuCrudController.php:
--------------------------------------------------------------------------------
1 | crud->setModel(Menu::class);
30 | $this->crud->setRoute(config('backpack.base.route_prefix') . '/menu');
31 | $this->crud->setEntityNameStrings('menu item', 'menu items');
32 | $this->crud->enableReorder('name', 2);
33 | }
34 |
35 | /**
36 | * Define what happens when the List operation is loaded.
37 | *
38 | * @see https://backpackforlaravel.com/docs/crud-operation-list-entries
39 | * @return void
40 | */
41 | protected function setupListOperation()
42 | {
43 | $this->authorize('browse', Menu::class);
44 |
45 | $this->crud->addColumn([
46 | 'name' => 'name',
47 | 'label' => 'Label',
48 | ]);
49 | $this->crud->addColumn([
50 | 'label' => 'Parent',
51 | 'type' => 'select',
52 | 'name' => 'parent_id',
53 | 'entity' => 'parent',
54 | 'attribute' => 'name',
55 | 'model' => Menu::class,
56 | ]);
57 | $this->crud->addColumn([
58 | 'name' => 'link',
59 | 'label' => 'Link',
60 | 'type' => 'url',
61 | ]);
62 | }
63 |
64 | /**
65 | * Define what happens when the Create operation is loaded.
66 | *
67 | * @see https://backpackforlaravel.com/docs/crud-operation-create
68 | * @return void
69 | */
70 | protected function setupCreateOperation()
71 | {
72 | $this->authorize('create', Menu::class);
73 |
74 | $this->crud->addField([
75 | 'name' => 'name',
76 | 'label' => 'Label',
77 | ]);
78 | $this->crud->addField([
79 | 'label' => 'Parent',
80 | 'type' => 'select',
81 | 'name' => 'parent_id',
82 | 'entity' => 'parent',
83 | 'attribute' => 'name',
84 | Menu::class
85 | ]);
86 |
87 | $this->crud->addField([
88 | 'name' => ['type', 'link', 'internal_link'],
89 | 'label' => 'Type',
90 | 'type' => 'page_or_link',
91 | ]);
92 | }
93 |
94 | /**
95 | * Define what happens when the Update operation is loaded.
96 | *
97 | * @see https://backpackforlaravel.com/docs/crud-operation-update
98 | * @return void
99 | */
100 | protected function setupUpdateOperation()
101 | {
102 | $this->authorize('update', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
103 |
104 |
105 | $this->setupCreateOperation();
106 | }
107 |
108 | protected function setupDeleteOperation()
109 | {
110 | $this->authorize('delete', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
111 | }
112 |
113 | public function bulkDelete()
114 | {
115 | $this->crud->hasAccessOrFail('bulkDelete');
116 | $entries = request()->input('entries', []);
117 | $deletedEntries = [];
118 | foreach ($entries as $key => $id) {
119 | if ($entry = $this->crud->model->find($id)) {
120 | $deletedEntries[] = $entry->delete();
121 | }
122 | }
123 |
124 | return $deletedEntries;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/PluginController.php:
--------------------------------------------------------------------------------
1 | crud->denyAccess('update');
28 | }
29 |
30 | /**
31 | * Define what happens when the List operation is loaded.
32 | *
33 | * @see https://backpackforlaravel.com/docs/crud-operation-list-entries
34 | * @return void
35 | */
36 | protected function setupListOperation()
37 | {
38 | if (!backpack_user()->hasPermissionTo('Browse plugin')) {
39 | abort(403);
40 | }
41 |
42 | CRUD::column('name')->label('Plugin')->type('text');
43 | CRUD::column('version')->label('Version')->type('text');
44 | $this->crud->addButtonFromModelFunction('line', 'editBtn', 'editBtn', 'beginning');
45 | $this->crud->addButtonFromModelFunction('line', 'openBtn', 'openBtn', 'beginning');
46 | }
47 |
48 | /**
49 | * Define what happens when the Update operation is loaded.
50 | *
51 | * @see https://backpackforlaravel.com/docs/crud-operation-update
52 | * @return void
53 | */
54 | protected function setupUpdateOperation()
55 | {
56 | $plugin = $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId());
57 |
58 | $fields = $plugin->options;
59 |
60 | CRUD::addField(['name' => 'fields', 'type' => 'hidden', 'value' => collect($fields)->implode('name', ',')]);
61 |
62 | foreach ($fields as $field) {
63 | CRUD::addField($field);
64 | }
65 | }
66 |
67 | public function show($id)
68 | {
69 | /** @var Plugin */
70 | $plugin = Plugin::findOrFail($id);
71 |
72 | return $plugin->open();
73 | }
74 |
75 | /**
76 | * Show the form for editing the specified resource.
77 | *
78 | * @return \Illuminate\Contracts\View\View
79 | */
80 | public function edit($id)
81 | {
82 | if (!backpack_user()->hasPermissionTo('Update plugin')) {
83 | abort(403);
84 | }
85 | $id = $this->crud->getCurrentEntryId() ?? $id;
86 |
87 | $this->data['entry'] = $this->crud->getEntryWithLocale($id);
88 | $this->crud->setOperationSetting('fields', $this->getUpdateFields());
89 |
90 | $this->data['crud'] = $this->crud;
91 | $this->data['saveAction'] = $this->crud->getSaveAction();
92 | $this->data['title'] = $this->crud->getTitle() ?? trans('backpack::crud.edit') . ' ' . $this->crud->entity_name;
93 | $this->data['id'] = $id;
94 |
95 | // load the view from /resources/views/vendor/backpack/crud/ if it exists, otherwise load the one in the package
96 | return view($this->crud->getEditView(), $this->data);
97 | }
98 |
99 | /**
100 | * Update the specified resource in the database.
101 | *
102 | * @return array|\Illuminate\Http\RedirectResponse
103 | */
104 | public function update($plugin)
105 | {
106 | if (!backpack_user()->hasPermissionTo('Update plugin')) {
107 | abort(403);
108 | }
109 |
110 | // execute the FormRequest authorization and validation, if one is required
111 | $request = $this->crud->validateRequest();
112 |
113 | // register any Model Events defined on fields
114 | $this->crud->registerFieldEvents();
115 |
116 | // update the row in the db
117 | $item = $this->crud->update(
118 | $request->get($this->crud->model->getKeyName()),
119 | [
120 | 'value' => request()->only(explode(',', request('fields')))
121 | ]
122 | );
123 | $this->data['entry'] = $this->crud->entry = $item;
124 |
125 | // show a success message
126 | Alert::success(trans('backpack::crud.update_success'))->flash();
127 |
128 | return redirect(backpack_url('plugin'));
129 | }
130 |
131 | /**
132 | * Get all fields needed for the EDIT ENTRY form.
133 | *
134 | * @param int $id The id of the entry that is being edited.
135 | * @return array The fields with attributes, fake attributes and values.
136 | */
137 | public function getUpdateFields($id = false)
138 | {
139 | $fields = $this->crud->fields();
140 | $entry = ($id != false) ? $this->getEntry($id) : $this->crud->getCurrentEntry();
141 | $options = $entry->value ?? [];
142 |
143 | foreach ($options as $k => $v) {
144 | $fields[$k]['value'] = $v;
145 | }
146 |
147 | if (!array_key_exists('id', $fields)) {
148 | $fields['id'] = [
149 | 'name' => $entry->getKeyName(),
150 | 'value' => $entry->getKey(),
151 | 'type' => 'hidden',
152 | ];
153 | }
154 |
155 | return $fields;
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/QuickActionController.php:
--------------------------------------------------------------------------------
1 | flash();
21 | return back();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/RegionCrudController.php:
--------------------------------------------------------------------------------
1 | authorize('browse', Region::class);
44 |
45 | /**
46 | * Columns can be defined using the fluent syntax or array syntax:
47 | * - CRUD::column('price')->label('price')->type('number');
48 | * - CRUD::addColumn(['name' => 'price', 'type' => 'number']);
49 | */
50 | CRUD::column('name')->label('Tên khu vực')->type('text');
51 | CRUD::column('slug')->label('Đường dẫn tĩnh')->type('text');
52 | CRUD::column('seo_title')->label('SEO Title')->type('text');
53 | CRUD::column('seo_des')->label('SEO Description')->type('text');
54 | CRUD::column('seo_key')->label('SEO Keyword')->type('text');
55 | }
56 |
57 | /**
58 | * Define what happens when the Create operation is loaded.
59 | *
60 | * @see https://backpackforlaravel.com/docs/crud-operation-create
61 | * @return void
62 | */
63 | protected function setupCreateOperation()
64 | {
65 | $this->authorize('create', Region::class);
66 |
67 | CRUD::setValidation(RegionRequest::class);
68 |
69 | /**
70 | * Fields can be defined using the fluent syntax or array syntax:
71 | * - CRUD::field('price')->label('price')->type('number');
72 | * - CRUD::addField(['name' => 'price', 'type' => 'number']));
73 | */
74 | CRUD::field('name')->label('Tên khu vực')->type('text');
75 | CRUD::field('slug')->label('Đường dẫn tĩnh')->type('text');
76 | CRUD::field('seo_title')->label('SEO Title')->type('text');
77 | CRUD::field('seo_des')->label('SEO Description')->type('textarea');
78 | CRUD::field('seo_key')->label('SEO Keyword')->type('text');
79 | }
80 | /**
81 | * Define what happens when the Update operation is loaded.
82 | *
83 | * @see https://backpackforlaravel.com/docs/crud-operation-update
84 | * @return void
85 | */
86 | protected function setupUpdateOperation()
87 | {
88 | $this->authorize('update', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
89 |
90 |
91 | $this->setupCreateOperation();
92 | }
93 |
94 | protected function setupDeleteOperation()
95 | {
96 | $this->authorize('delete', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/StudioCrudController.php:
--------------------------------------------------------------------------------
1 | authorize('browse', Studio::class);
44 |
45 | /**
46 | * Columns can be defined using the fluent syntax or array syntax:
47 | * - CRUD::column('price')->type('number');
48 | * - CRUD::addColumn(['name' => 'price', 'type' => 'number']);
49 | */
50 |
51 | CRUD::addColumn(['name' => 'name', 'label' => 'Tên', 'type' => 'text']);
52 | CRUD::addColumn(['name' => 'slug', 'label' => 'Đường dẫn tĩnh', 'type' => 'text']);
53 | CRUD::addColumn(['name' => 'image', 'label' => 'Ảnh', 'type' => 'image']);
54 | }
55 |
56 | /**
57 | * Define what happens when the Create operation is loaded.
58 | *
59 | * @see https://backpackforlaravel.com/docs/crud-operation-create
60 | * @return void
61 | */
62 | protected function setupCreateOperation()
63 | {
64 | $this->authorize('create', Studio::class);
65 |
66 | CRUD::setValidation(StudioRequest::class);
67 |
68 | /**
69 | * Fields can be defined using the fluent syntax or array syntax:
70 | * - CRUD::field('price')->type('number');
71 | * - CRUD::addField(['name' => 'price', 'type' => 'number']));
72 | */
73 |
74 | CRUD::addField(['name' => 'name', 'label' => 'Tên', 'type' => 'text']);
75 | CRUD::addField(['name' => 'slug', 'label' => 'Đường dẫn tĩnh', 'type' => 'text']);
76 | CRUD::addField(['name' => 'image', 'label' => 'Ảnh', 'type' => 'upload']);
77 | }
78 |
79 | /**
80 | * Define what happens when the Update operation is loaded.
81 | *
82 | * @see https://backpackforlaravel.com/docs/crud-operation-update
83 | * @return void
84 | */
85 | protected function setupUpdateOperation()
86 | {
87 | $this->authorize('update', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
88 |
89 |
90 | $this->setupCreateOperation();
91 | }
92 |
93 | protected function setupDeleteOperation()
94 | {
95 | $this->authorize('delete', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/Controllers/Admin/TagCrudController.php:
--------------------------------------------------------------------------------
1 | authorize('browse', Tag::class);
44 |
45 | /**
46 | * Columns can be defined using the fluent syntax or array syntax:
47 | * - CRUD::column('price')->type('number');
48 | * - CRUD::addColumn(['name' => 'price', 'type' => 'number']);
49 | */
50 |
51 | CRUD::addColumn(['name' => 'name', 'type' => 'text']);
52 | CRUD::addColumn(['name' => 'slug', 'type' => 'text']);
53 | }
54 |
55 | /**
56 | * Define what happens when the Create operation is loaded.
57 | *
58 | * @see https://backpackforlaravel.com/docs/crud-operation-create
59 | * @return void
60 | */
61 | protected function setupCreateOperation()
62 | {
63 | $this->authorize('create', Tag::class);
64 |
65 | CRUD::setValidation(TagRequest::class);
66 |
67 | /**
68 | * Fields can be defined using the fluent syntax or array syntax:
69 | * - CRUD::field('price')->type('number');
70 | * - CRUD::addField(['name' => 'price', 'type' => 'number']));
71 | */
72 |
73 | CRUD::addField(['name' => 'name', 'type' => 'text']);
74 | CRUD::addField(['name' => 'slug', 'type' => 'text']);
75 | }
76 |
77 | /**
78 | * Define what happens when the Update operation is loaded.
79 | *
80 | * @see https://backpackforlaravel.com/docs/crud-operation-update
81 | * @return void
82 | */
83 | protected function setupUpdateOperation()
84 | {
85 | $this->authorize('update', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
86 |
87 |
88 | $this->setupCreateOperation();
89 | }
90 |
91 | protected function setupDeleteOperation()
92 | {
93 | $this->authorize('delete', $this->crud->getEntryWithLocale($this->crud->getCurrentEntryId()));
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 | options, 'value', 'name') ?? [],
18 | is_array($theme->value) ? $theme->value : []
19 | ));
20 |
21 | return $props[$key] ?? $fallback;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Middleware/CKFinderAuth.php:
--------------------------------------------------------------------------------
1 | function () {
21 | return true;
22 | }]);
23 |
24 | return $next($request);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Middleware/EncryptCookies.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | 'ckCsrfToken'
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/src/Middleware/VerifyCsrfToken.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | 'ckfinder/*',
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/src/Models/Catalog.php:
--------------------------------------------------------------------------------
1 | slug;
60 | if (strpos($site_routes, '{id}')) $params['id'] = $this->id;
61 | return route('types.movies.index', $params);
62 | }
63 |
64 | public function generateSeoTags()
65 | {
66 | $seo_title = $this->seo_title;
67 | $seo_des = $this->seo_des;
68 | $seo_key = $this->seo_key;
69 | $getUrl = $this->getUrl();
70 | $site_meta_siteName = setting('site_meta_siteName');
71 |
72 | SEOMeta::setTitle($seo_title, false)
73 | ->setDescription($seo_des)
74 | ->addKeyword([$seo_key])
75 | ->setCanonical($getUrl)
76 | ->setPrev(request()->root())
77 | ->setPrev(request()->root());
78 |
79 | OpenGraph::setSiteName($site_meta_siteName)
80 | ->setType('website')
81 | ->setTitle($seo_title, false)
82 | ->addProperty('locale', 'vi-VN')
83 | ->addProperty('url', $getUrl)
84 | ->setDescription($seo_des);
85 |
86 | TwitterCard::setSite($site_meta_siteName)
87 | ->setTitle($seo_title, false)
88 | ->setType('summary')
89 | ->setDescription($seo_des)
90 | ->setUrl($getUrl);
91 |
92 | JsonLdMulti::newJsonLd()
93 | ->setSite($site_meta_siteName)
94 | ->setTitle($seo_title, false)
95 | ->setType('WebPage')
96 | ->setDescription($seo_des)
97 | ->setUrl($getUrl);
98 |
99 | $breadcrumb = [];
100 | array_push($breadcrumb, [
101 | '@type' => 'ListItem',
102 | 'position' => 1,
103 | 'name' => 'Home',
104 | 'item' => url('/')
105 | ]);
106 | array_push($breadcrumb, [
107 | '@type' => 'ListItem',
108 | 'position' => 2,
109 | 'name' => $this->name,
110 | 'item' => $getUrl
111 | ]);
112 | array_push($breadcrumb, [
113 | '@type' => 'ListItem',
114 | 'position' => 3,
115 | 'name' => "Trang " . (request()->get('page') ?: 1),
116 | ]);
117 | JsonLdMulti::newJsonLd()
118 | ->setType('BreadcrumbList')
119 | ->addValue('name', '')
120 | ->addValue('description', '')
121 | ->addValue('itemListElement', $breadcrumb);
122 | }
123 |
124 | public function openView($crud = false)
125 | {
126 | return ' View';
127 | }
128 |
129 |
130 | /*
131 | |--------------------------------------------------------------------------
132 | | RELATIONS
133 | |--------------------------------------------------------------------------
134 | */
135 |
136 | /*
137 | |--------------------------------------------------------------------------
138 | | SCOPES
139 | |--------------------------------------------------------------------------
140 | */
141 |
142 | /*
143 | |--------------------------------------------------------------------------
144 | | ACCESSORS
145 | |--------------------------------------------------------------------------
146 | */
147 |
148 | /*
149 | |--------------------------------------------------------------------------
150 | | MUTATORS
151 | |--------------------------------------------------------------------------
152 | */
153 | }
154 |
--------------------------------------------------------------------------------
/src/Models/Menu.php:
--------------------------------------------------------------------------------
1 | belongsTo(static::class, 'parent_id');
23 | }
24 |
25 | public function children()
26 | {
27 | return $this->hasMany(static::class, 'parent_id');
28 | }
29 |
30 | /**
31 | * Get all menu items, in a hierarchical collection.
32 | * Only supports 2 levels of indentation.
33 | */
34 | public static function getTree()
35 | {
36 | $menu = self::fromCache()->all()->sortBy('lft');
37 |
38 | if ($menu->count()) {
39 | foreach ($menu as $k => $menu_item) {
40 | $menu_item->children = collect([]);
41 |
42 | foreach ($menu as $i => $menu_subitem) {
43 | if ($menu_subitem->parent_id == $menu_item->id) {
44 | $menu_item->children->push($menu_subitem);
45 |
46 | // remove the subitem for the first level
47 | $menu = $menu->reject(function ($item) use ($menu_subitem) {
48 | return $item->id == $menu_subitem->id;
49 | });
50 | }
51 | }
52 | }
53 | }
54 |
55 | return $menu;
56 | }
57 |
58 | public function url()
59 | {
60 | switch ($this->type) {
61 | case 'external_link':
62 | return $this->link;
63 | break;
64 |
65 | case 'internal_link':
66 | return is_null($this->link) ? '#' : url($this->link);
67 | break;
68 |
69 | default: //page_link
70 | if ($this->page) {
71 | return url($this->page->slug);
72 | }
73 | break;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Models/Studio.php:
--------------------------------------------------------------------------------
1 | slug);
63 | }
64 |
65 | protected function titlePattern(): string
66 | {
67 | return Setting::get('site_studio_title', '');
68 | }
69 |
70 | protected function descriptionPattern(): string
71 | {
72 | return Setting::get('site_region_des', '');
73 | }
74 |
75 | protected function keywordsPattern(): string
76 | {
77 | return Setting::get('site_region_key', '');
78 | }
79 |
80 | public function generateSeoTags()
81 | {
82 | $seo_title = $this->getTitle();
83 | $seo_des = Str::limit($this->getDescription(), 150, '...');
84 | $seo_key = $this->getKeywords();
85 |
86 | SEOMeta::setTitle($seo_title, false)
87 | ->setDescription($seo_des)
88 | ->addKeyword([$seo_key])
89 | ->setCanonical($this->getUrl())
90 | ->setPrev(request()->root())
91 | ->setPrev(request()->root());
92 | // ->addMeta($meta, $value, 'property');
93 |
94 | OpenGraph::setSiteName(setting('site_meta_siteName'))
95 | ->setTitle($seo_title, false)
96 | ->addProperty('type', 'movie')
97 | ->addProperty('locale', 'vi-VN')
98 | ->addProperty('url', $this->getUrl())
99 | ->setDescription($seo_des)
100 | ->addImages([$this->thumb_url, $this->poster_url]);
101 |
102 | TwitterCard::setSite(setting('site_meta_siteName'))
103 | ->setTitle($seo_title, false)
104 | ->setType('movie')
105 | ->setImage($this->thumb_url)
106 | ->setDescription($seo_des)
107 | ->setUrl($this->getUrl());
108 | // ->addValue($key, $value);
109 |
110 | JsonLdMulti::newJsonLd()
111 | ->setSite(setting('site_meta_siteName'))
112 | ->setTitle($seo_title, false)
113 | ->setType('movie')
114 | ->setDescription($seo_des)
115 | ->setUrl($this->getUrl());
116 | // ->addValue($key, $value);
117 | }
118 |
119 |
120 |
121 | /*
122 | |--------------------------------------------------------------------------
123 | | RELATIONS
124 | |--------------------------------------------------------------------------
125 | */
126 |
127 | public function movies()
128 | {
129 | return $this->belongsToMany(Movie::class);
130 | }
131 |
132 | /*
133 | |--------------------------------------------------------------------------
134 | | SCOPES
135 | |--------------------------------------------------------------------------
136 | */
137 |
138 | /*
139 | |--------------------------------------------------------------------------
140 | | ACCESSORS
141 | |--------------------------------------------------------------------------
142 | */
143 |
144 | /*
145 | |--------------------------------------------------------------------------
146 | | MUTATORS
147 | |--------------------------------------------------------------------------
148 | */
149 | }
150 |
--------------------------------------------------------------------------------
/src/Models/Theme.php:
--------------------------------------------------------------------------------
1 | 'array',
33 | ];
34 |
35 | public static function getActivatedTheme(): ?self
36 | {
37 | return Theme::where('active', true)->first() ?: Theme::first();
38 | }
39 |
40 | public function getVersionAttribute()
41 | {
42 | if (!\Composer\InstalledVersions::isInstalled($this->package_name)) {
43 | return 'Unknown';
44 | }
45 |
46 | return \PackageVersions\Versions::getVersion($this->package_name);
47 | }
48 |
49 | public function getOptionsAttribute()
50 | {
51 | $allThemes = config('themes', []);
52 |
53 | if (!isset($allThemes[strtolower($this->name)]['options'])) {
54 | return [];
55 | }
56 |
57 | return $allThemes[strtolower($this->name)]['options'];
58 | }
59 |
60 | public function editBtn($crud = false)
61 | {
62 | return 'id}/edit") . '" class="btn btn-primary">Edit';
63 | }
64 |
65 | public function deleteBtn($crud = false)
66 | {
67 | if ($this->getVersionAttribute() === 'Unknown') {
68 |
69 | $template = <<
71 | {csrfField}
72 |
73 |
74 | EOT;
75 | $html = str_replace("{actionRoute}", backpack_url("theme/{$this->id}/delete"), $template);
76 | $html = str_replace("{csrfField}", csrf_field(), $html);
77 | $html = str_replace("{display_name}", $this->display_name, $html);
78 |
79 | return $html;
80 | }
81 | return '';
82 | }
83 |
84 | public function activeBtn($crud = false)
85 | {
86 | $template = <<
88 | {csrfField}
89 |
90 |
91 | EOT;
92 |
93 | $html = str_replace("{actionRoute}", backpack_url("theme/{$this->id}/active"), $template);
94 | $html = str_replace("{csrfField}", csrf_field(), $html);
95 | $html = str_replace("{display_name}", $this->display_name, $html);
96 |
97 | if ($this->active) {
98 | $html = str_replace("{name}", 'Re-Activate', $html);
99 | $html = str_replace("{btnType}", 'btn-secondary', $html);
100 | } else {
101 | $html = str_replace("{name}", 'Activate', $html);
102 | $html = str_replace("{btnType}", 'btn-primary', $html);
103 | }
104 |
105 | return $html;
106 | }
107 |
108 | public function resetBtn($crud = false)
109 | {
110 | $template = <<
112 | {csrfField}
113 |
114 |
115 | EOT;
116 |
117 | $html = str_replace("{actionRoute}", backpack_url("theme/{$this->id}/reset"), $template);
118 | $html = str_replace("{csrfField}", csrf_field(), $html);
119 | $html = str_replace("{btnType}", 'btn-warning', $html);
120 | $html = str_replace("{name}", 'Reset', $html);
121 |
122 | return $html;
123 | }
124 |
125 | public function active()
126 | {
127 | static::where('active', true)->update(['active' => false]);
128 |
129 | $publishTags = config('themes', [])[$this->name]['publishes'] ?? [];
130 |
131 | foreach ($publishTags as $tag) {
132 | Artisan::call('vendor:publish', [
133 | '--tag' => $tag,
134 | '--force' => true
135 | ]);
136 | }
137 |
138 | return $this->update(['active' => true]);
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/Models/User.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse user');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create user');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update user');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete user');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/CatalogPolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse catalog');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create catalog');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update catalog');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete catalog');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/CategoryPolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse category');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create category');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update category');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete category');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/CrawlSchedulePolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse crawl schedule');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create crawl schedule');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update crawl schedule');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete crawl schedule');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/DirectorPolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse director');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create director');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update director');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete director');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/EpisodePolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse episode');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create episode');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update episode');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete episode');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Policies/MenuPolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse menu');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create menu');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update menu');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete menu');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/MoviePolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse movie');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create movie');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update movie');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete movie');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/PermissionPolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
15 | return true;
16 | }
17 | }
18 |
19 | public function browse($user)
20 | {
21 | return $user->hasPermissionTo('Browse permission');
22 | }
23 |
24 | public function create($user)
25 | {
26 | return $user->hasPermissionTo('Create permission');
27 | }
28 |
29 | public function update($user, $entry)
30 | {
31 | return $user->hasPermissionTo('Update permission');
32 | }
33 |
34 | public function delete($user, $entry)
35 | {
36 | return $user->hasPermissionTo('Delete permission');
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/Policies/RegionPolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse region');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create region');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update region');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete region');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/RolePolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse role');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create role');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update role');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete role');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/StudioPolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse studio');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create studio');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update studio');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete studio');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/TagPolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse tag');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create tag');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update tag');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete tag');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Policies/UserPolicy.php:
--------------------------------------------------------------------------------
1 | hasRole('Admin')) {
14 | return true;
15 | }
16 | }
17 |
18 | public function browse($user)
19 | {
20 | return $user->hasPermissionTo('Browse user');
21 | }
22 |
23 | public function create($user)
24 | {
25 | return $user->hasPermissionTo('Create user');
26 | }
27 |
28 | public function update($user, $entry)
29 | {
30 | return $user->hasPermissionTo('Update user');
31 | }
32 |
33 | public function delete($user, $entry)
34 | {
35 | return $user->hasPermissionTo('Delete user');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Requests/ActorRequest.php:
--------------------------------------------------------------------------------
1 | check();
19 | }
20 |
21 | /**
22 | * Get the validation rules that apply to the request.
23 | *
24 | * @return array
25 | */
26 | public function rules()
27 | {
28 | $this->name_md5 = md5($this->name);
29 |
30 | return [
31 | 'name' => ['required', 'max:255', new UniqueName('actors', 'name', 'name_md5', 'id', $this->id)],
32 | 'slug' => 'max:255|unique:actors,slug,' . $this->id . ',id',
33 | ];
34 | }
35 |
36 | /**
37 | * Get the validation attributes that apply to the request.
38 | *
39 | * @return array
40 | */
41 | public function attributes()
42 | {
43 | return [
44 | //
45 | ];
46 | }
47 |
48 | /**
49 | * Get the validation messages that apply to the request.
50 | *
51 | * @return array
52 | */
53 | public function messages()
54 | {
55 | return [
56 | //
57 | ];
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Requests/CatalogRequest.php:
--------------------------------------------------------------------------------
1 | check();
18 | }
19 |
20 | /**
21 | * Get the validation rules that apply to the request.
22 | *
23 | * @return array
24 | */
25 | public function rules()
26 | {
27 | return [
28 | 'name' => 'required|min:5|max:255',
29 | 'slug' => 'max:255|unique:catalogs,slug,' . $this->id . ',id',
30 | 'value' => 'string',
31 | 'seo_title' => 'string|max:255',
32 | 'seo_des' => 'string|max:255',
33 | 'seo_key' => 'string|max:255',
34 | ];
35 | }
36 |
37 | /**
38 | * Get the validation attributes that apply to the request.
39 | *
40 | * @return array
41 | */
42 | public function attributes()
43 | {
44 | return [
45 | //
46 | ];
47 | }
48 |
49 | /**
50 | * Get the validation messages that apply to the request.
51 | *
52 | * @return array
53 | */
54 | public function messages()
55 | {
56 | return [
57 | //
58 | ];
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Requests/CategoryRequest.php:
--------------------------------------------------------------------------------
1 | check();
18 | }
19 |
20 | /**
21 | * Get the validation rules that apply to the request.
22 | *
23 | * @return array
24 | */
25 | public function rules()
26 | {
27 | return [
28 | 'name' => 'required|min:5|max:255',
29 | 'slug' => 'max:255|unique:categories,slug,' . $this->id . ',id',
30 | 'seo_title' => 'string|max:255',
31 | 'seo_des' => 'string|max:255',
32 | 'seo_key' => 'string|max:255',
33 | ];
34 | }
35 |
36 | /**
37 | * Get the validation attributes that apply to the request.
38 | *
39 | * @return array
40 | */
41 | public function attributes()
42 | {
43 | return [
44 | //
45 | ];
46 | }
47 |
48 | /**
49 | * Get the validation messages that apply to the request.
50 | *
51 | * @return array
52 | */
53 | public function messages()
54 | {
55 | return [
56 | //
57 | ];
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Requests/CrawlScheduleRequest.php:
--------------------------------------------------------------------------------
1 | check();
18 | }
19 |
20 | /**
21 | * Get the validation rules that apply to the request.
22 | *
23 | * @return array
24 | */
25 | public function rules()
26 | {
27 | return [
28 | 'type' => 'required',
29 | 'fields' => 'required'
30 | ];
31 | }
32 |
33 | /**
34 | * Get the validation attributes that apply to the request.
35 | *
36 | * @return array
37 | */
38 | public function attributes()
39 | {
40 | return [
41 | //
42 | ];
43 | }
44 |
45 | /**
46 | * Get the validation messages that apply to the request.
47 | *
48 | * @return array
49 | */
50 | public function messages()
51 | {
52 | return [
53 | //
54 | ];
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Requests/DirectorRequest.php:
--------------------------------------------------------------------------------
1 | check();
19 | }
20 |
21 | /**
22 | * Get the validation rules that apply to the request.
23 | *
24 | * @return array
25 | */
26 | public function rules()
27 | {
28 | $this->name_md5 = md5($this->name);
29 |
30 | return [
31 | 'name' => ['required', 'max:255', new UniqueName('directors', 'name', 'name_md5', 'id', $this->id)],
32 | 'slug' => 'max:255|unique:directors,slug,' . $this->id . ',id',
33 | ];
34 | }
35 |
36 | /**
37 | * Get the validation attributes that apply to the request.
38 | *
39 | * @return array
40 | */
41 | public function attributes()
42 | {
43 | return [
44 | //
45 | ];
46 | }
47 |
48 | /**
49 | * Get the validation messages that apply to the request.
50 | *
51 | * @return array
52 | */
53 | public function messages()
54 | {
55 | return [
56 | //
57 | ];
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Requests/MenuRequest.php:
--------------------------------------------------------------------------------
1 | check();
18 | }
19 |
20 | /**
21 | * Get the validation rules that apply to the request.
22 | *
23 | * @return array
24 | */
25 | public function rules()
26 | {
27 | return [
28 | 'name' => 'required|max:255',
29 | 'type' => 'required',
30 | 'link' => 'required|max:2048'
31 | ];
32 | }
33 |
34 | /**
35 | * Get the validation attributes that apply to the request.
36 | *
37 | * @return array
38 | */
39 | public function attributes()
40 | {
41 | return [
42 | //
43 | ];
44 | }
45 |
46 | /**
47 | * Get the validation messages that apply to the request.
48 | *
49 | * @return array
50 | */
51 | public function messages()
52 | {
53 | return [
54 | //
55 | ];
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Requests/MovieRequest.php:
--------------------------------------------------------------------------------
1 | check();
18 | }
19 |
20 | /**
21 | * Get the validation rules that apply to the request.
22 | *
23 | * @return array
24 | */
25 | public function rules()
26 | {
27 | return [
28 | 'name' => 'required|max:512',
29 | 'origin_name' => 'required|max:512',
30 | 'slug' => 'max:255|unique:movies,slug,' . $this->id . ',id',
31 | 'type' => 'required|in:single,series',
32 | 'status' => 'required|in:trailer,ongoing,completed',
33 | ];
34 | }
35 |
36 | /**
37 | * Get the validation attributes that apply to the request.
38 | *
39 | * @return array
40 | */
41 | public function attributes()
42 | {
43 | return [
44 | //
45 | ];
46 | }
47 |
48 | /**
49 | * Get the validation messages that apply to the request.
50 | *
51 | * @return array
52 | */
53 | public function messages()
54 | {
55 | return [
56 | //
57 | ];
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Requests/RegionRequest.php:
--------------------------------------------------------------------------------
1 | check();
18 | }
19 |
20 | /**
21 | * Get the validation rules that apply to the request.
22 | *
23 | * @return array
24 | */
25 | public function rules()
26 | {
27 | return [
28 | 'name' => 'required|min:5|max:255',
29 | 'slug' => 'max:255|unique:regions,slug,' . $this->id . ',id',
30 | 'seo_title' => 'string|max:255',
31 | 'seo_des' => 'string|max:255',
32 | 'seo_key' => 'string|max:255',
33 | ];
34 | }
35 |
36 | /**
37 | * Get the validation attributes that apply to the request.
38 | *
39 | * @return array
40 | */
41 | public function attributes()
42 | {
43 | return [
44 | //
45 | ];
46 | }
47 |
48 | /**
49 | * Get the validation messages that apply to the request.
50 | *
51 | * @return array
52 | */
53 | public function messages()
54 | {
55 | return [
56 | //
57 | ];
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Requests/StudioRequest.php:
--------------------------------------------------------------------------------
1 | check();
18 | }
19 |
20 | /**
21 | * Get the validation rules that apply to the request.
22 | *
23 | * @return array
24 | */
25 | public function rules()
26 | {
27 | return [
28 | 'name' => 'required|string|max:512',
29 | 'slug' => 'max:255|unique:studios,slug,' . $this->id . ',id',
30 | ];
31 | }
32 |
33 | /**
34 | * Get the validation attributes that apply to the request.
35 | *
36 | * @return array
37 | */
38 | public function attributes()
39 | {
40 | return [
41 | //
42 | ];
43 | }
44 |
45 | /**
46 | * Get the validation messages that apply to the request.
47 | *
48 | * @return array
49 | */
50 | public function messages()
51 | {
52 | return [
53 | //
54 | ];
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Requests/TagRequest.php:
--------------------------------------------------------------------------------
1 | check();
20 | }
21 |
22 | /**
23 | * Get the validation rules that apply to the request.
24 | *
25 | * @return array
26 | */
27 | public function rules()
28 | {
29 | return [
30 | 'name' => ['required', 'max:255', new UniqueName('tags', 'name', 'name_md5', 'id', $this->id)],
31 | ];
32 | }
33 |
34 | /**
35 | * Get the validation attributes that apply to the request.
36 | *
37 | * @return array
38 | */
39 | public function attributes()
40 | {
41 | return [
42 | //
43 | ];
44 | }
45 |
46 | /**
47 | * Get the validation messages that apply to the request.
48 | *
49 | * @return array
50 | */
51 | public function messages()
52 | {
53 | return [
54 | //
55 | ];
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Rules/UniqueName.php:
--------------------------------------------------------------------------------
1 | table = $table;
24 | $this->md5Field = $md5Field;
25 | $this->excludeField = $excludeField;
26 | $this->excludeVal = $excludeVal;
27 | $this->nameField = $nameField;
28 | }
29 |
30 | /**
31 | * Determine if the validation rule passes.
32 | *
33 | * @param string $attribute
34 | * @param mixed $value
35 | * @return bool
36 | */
37 | public function passes($attribute, $value)
38 | {
39 | return DB::table($this->table)->where($this->excludeField, '!=', $this->excludeVal)->where($this->md5Field, md5($value))->doesntExist();
40 | }
41 |
42 | /**
43 | * Get the validation error message.
44 | *
45 | * @return string
46 | */
47 | public function message()
48 | {
49 | return ":attribute must be unique";
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Theme.php:
--------------------------------------------------------------------------------
1 | payload = $payload;
19 |
20 | $this->name = ThemeModel::getActivatedTheme()->name;
21 |
22 | if (is_null($this->name)) {
23 | throw new \Exception("Not found any theme. Please install and active one.");;
24 | }
25 |
26 | $this->themePath = $this->namespace . '::' . $this->name;
27 | }
28 |
29 | public function render($template, array $data = [])
30 | {
31 | $viewPath = sprintf("%s.%s", $this->themePath, $template);
32 | if (!view()->exists($viewPath)) {
33 | throw new Exception("Theme {$this->name}'s {$template} view is not installed. Please check your installation");
34 | }
35 |
36 | return view($viewPath, array_merge($this->payload, $data));
37 | }
38 |
39 | public function addPayload(array $data)
40 | {
41 | $this->payload = array_merge($this->payload, $data);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Traits/ActorLog.php:
--------------------------------------------------------------------------------
1 | user_id = auth('backpack')->id() ?: $instance->user_id;
11 | $instance->user_name = auth('backpack')->user() ? auth('backpack')->user()->name : $instance->username;
12 | });
13 |
14 | static::updating(function ($instance) {
15 | $instance->user_id = auth('backpack')->id() ?: $instance->user_id;
16 | $instance->user_name = auth('backpack')->user() ? auth('backpack')->user()->name : $instance->username;
17 | });
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Traits/HasDescription.php:
--------------------------------------------------------------------------------
1 | descriptionPattern();
18 |
19 | preg_match_all('/{.*?}/', $pattern, $vars);
20 |
21 | foreach ($vars[0] as $var) {
22 | try {
23 | $x = str_replace('{', '', $var);
24 | $x = str_replace('}', '', $x);
25 | $keys = explode('.', (string) $x);
26 | $data = $this;
27 | foreach ($keys as $key) {
28 | $data = $data->{$key};
29 | }
30 | $pattern = str_replace($var, $data, $pattern);
31 | } catch (\Exception $e) {
32 | }
33 | }
34 |
35 | return $pattern;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Traits/HasFactory.php:
--------------------------------------------------------------------------------
1 | keywordsPattern();
18 |
19 | preg_match_all('/{.*?}/', $pattern, $vars);
20 |
21 | foreach ($vars[0] as $var) {
22 | try {
23 | $x = str_replace('{', '', $var);
24 | $x = str_replace('}', '', $x);
25 | $keys = explode('.', (string) $x);
26 | $data = $this;
27 | foreach ($keys as $key) {
28 | $data = $data->{$key};
29 | }
30 | $pattern = str_replace($var, $data, $pattern);
31 | } catch (\Exception $e) {
32 | }
33 | }
34 |
35 | return $pattern;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Traits/HasTitle.php:
--------------------------------------------------------------------------------
1 | titlePattern();
18 |
19 | preg_match_all('/{.*?}/', $pattern, $vars);
20 |
21 | foreach ($vars[0] as $var) {
22 | try {
23 | $x = str_replace('{', '', $var);
24 | $x = str_replace('}', '', $x);
25 | $keys = explode('.', (string) $x);
26 | $data = $this;
27 | foreach ($keys as $key) {
28 | $data = $data->{$key};
29 | }
30 | $pattern = str_replace($var, $data, $pattern);
31 | } catch (\Exception $e) {
32 | }
33 | }
34 |
35 | return $pattern;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Traits/HasUniqueName.php:
--------------------------------------------------------------------------------
1 | name_md5 = md5($instance->name);
18 | });
19 |
20 | static::updating(function ($instance) {
21 | $instance->name_md5 = md5($instance->name);
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Traits/Operations/BulkDeleteOperation.php:
--------------------------------------------------------------------------------
1 | $routeName.'.bulkDelete',
13 | 'uses' => $controller.'@bulkDelete',
14 | 'operation' => 'bulkDelete',
15 | ]);
16 | }
17 |
18 | protected function setupBulkDeleteDefaults()
19 | {
20 | $this->crud->allowAccess('bulkDelete');
21 |
22 | $this->crud->operation('bulkDelete', function () {
23 | $this->crud->loadDefaultOperationSettingsFromConfig();
24 | });
25 |
26 | $this->crud->operation('list', function () {
27 | $this->crud->enableBulkActions();
28 | $this->crud->addButton('bottom', 'bulk_delete', 'view', 'crud::buttons.bulk_delete');
29 | });
30 | }
31 |
32 | public function bulkDelete()
33 | {
34 | $this->crud->hasAccessOrFail('bulkDelete');
35 | $entries = request()->input('entries', []);
36 | $deletedEntries = [];
37 |
38 | foreach ($entries as $key => $id) {
39 | if ($entry = $this->crud->model->find($id)) {
40 | $deletedEntries[] = $entry->delete();
41 | }
42 | }
43 |
44 | return $deletedEntries;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Traits/Sluggable.php:
--------------------------------------------------------------------------------
1 | slug)) {
18 | $slug = Str::slug($instance->name) ?: $instance->name;
19 | $instance->slug = static::where('slug', $slug)->exists()
20 | ? sprintf("%s-%s%s", $slug, floor(microtime(true) * 1000), rand(1, 100))
21 | : $slug;
22 | }
23 | });
24 |
25 | static::updating(function ($instance) {
26 | if (empty($instance->slug)) {
27 | $slug = Str::slug($instance->name) ?: $instance->name;
28 | $instance->slug = static::where('slug', $slug)->exists()
29 | ? sprintf("%s-%s%s", $slug, floor(microtime(true) * 1000), rand(1, 100))
30 | : $slug;
31 | }
32 | });
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/tests/databases/DatabaseTesting.php:
--------------------------------------------------------------------------------
1 | call([
30 | CategoriesTableSeeder::class,
31 | RegionsTableSeeder::class,
32 | ThemesTableSeeder::class,
33 | MenusTableSeeder::class,
34 | SettingsTableSeeder::class,
35 | ]);
36 |
37 | Actor::factory(100)->create();
38 | Director::factory(100)->create();
39 | Tag::factory(100)->create();
40 |
41 | for ($i = 1; $i < 1000; $i++) {
42 | Movie::factory(1)
43 | ->state([
44 | 'publish_year' => rand(2018, 2022)
45 | ])
46 | ->hasAttached(Region::all()->random())
47 | ->hasAttached(Category::all()->random(3))
48 | ->hasAttached(Actor::all()->random(rand(1, 5)))
49 | ->hasAttached(Director::all()->random(1))
50 | ->hasAttached(Tag::all()->random(5))
51 | ->has(Episode::factory(5)->state([
52 | 'server' => 'Vietsub #1',
53 | 'type' => 'embed',
54 | 'link' => 'https://aa.nguonphimmoi.com/20220309/2918_589b816d/index.m3u8'
55 | ]))
56 | ->create();
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/webpack.mix.js:
--------------------------------------------------------------------------------
1 | const mix = require('laravel-mix');
2 |
3 | /*
4 | |--------------------------------------------------------------------------
5 | | Mix Asset Management
6 | |--------------------------------------------------------------------------
7 | |
8 | | Mix provides a clean, fluent API for defining some Webpack build steps
9 | | for your Laravel applications. By default, we are compiling the CSS
10 | | file for the application as well as bundling up all the JS files.
11 | |
12 | */
13 |
14 |
15 |
--------------------------------------------------------------------------------