section basic

This commit is contained in:
xiaomlove
2022-10-27 20:21:54 +08:00
parent 0053d14183
commit ce5d99c16a
92 changed files with 3188 additions and 1367 deletions

View File

@@ -36,7 +36,7 @@ Complete PT website building solution. Based on NexusPHP + Laravel + Filament.
- Custom role permission
- Section H&R
## System Requirements
- PHP: 8.0, must have extensions: bcmath, ctype, curl, fileinfo, json, mbstring, openssl, pdo_mysql, tokenizer, xml, mysqli, gd, redis, pcntl, sockets, posix, gmp
- PHP: 8.0, must have extensions: bcmath, ctype, curl, fileinfo, json, mbstring, openssl, pdo_mysql, tokenizer, xml, mysqli, gd, redis, pcntl, sockets, posix, gmp, zend opcache
- Mysql: 5.7 latest version or above
- Redis2.6.12 or above

View File

@@ -36,7 +36,7 @@
- 分区 H&R
## 系统要求
- PHP: 8.0必须扩展bcmath, ctype, curl, fileinfo, json, mbstring, openssl, pdo_mysql, tokenizer, xml, mysqli, gd, redis, pcntl, sockets, posix, gmp
- PHP: 8.0必须扩展bcmath, ctype, curl, fileinfo, json, mbstring, openssl, pdo_mysql, tokenizer, xml, mysqli, gd, redis, pcntl, sockets, posix, gmp, zend opcache
- Mysql: 5.7 最新版或以上版本
- Redis2.6.12 或以上版本

View File

@@ -90,7 +90,8 @@ class Test extends Command
*/
public function handle()
{
$r = SearchBox::getSubCatOptions();
dd($r);
}

View File

@@ -29,7 +29,7 @@ class Kernel extends ConsoleKernel
$schedule->command('exam:checkout_cronjob')->everyMinute()->withoutOverlapping();
$schedule->command('exam:update_progress --bulk=1')->hourly()->withoutOverlapping();
$schedule->command('backup:cronjob')->everyMinute()->withoutOverlapping();
$schedule->command('hr:update_status')->everyMinute()->withoutOverlapping();
$schedule->command('hr:update_status')->everyTenMinutes()->withoutOverlapping();
$schedule->command('hr:update_status --ignore_time=1')->hourly()->withoutOverlapping();
$schedule->command('user:delete_expired_token')->dailyAt('04:00');
$schedule->command('claim:settle')->hourly()->when(function () {

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Filament\Resources\Section;
use App\Filament\Resources\Section\AudioCodecResource\Pages;
use App\Filament\Resources\Section\AudioCodecResource\RelationManagers;
use App\Models\AudioCodec;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class AudioCodecResource extends CodecResource
{
protected static ?string $model = AudioCodec::class;
protected static ?int $navigationSort = 4;
public static function form(Form $form): Form
{
return parent::form($form);
}
public static function table(Table $table): Table
{
return parent::table($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListAudioCodecs::route('/'),
'create' => Pages\CreateAudioCodec::route('/create'),
'edit' => Pages\EditAudioCodec::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\Section\AudioCodecResource\Pages;
use App\Filament\Resources\Section\AudioCodecResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateAudioCodec extends CreateRecord
{
protected static string $resource = AudioCodecResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Section\AudioCodecResource\Pages;
use App\Filament\Resources\Section\AudioCodecResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditAudioCodec extends EditRecord
{
protected static string $resource = AudioCodecResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Filament\Resources\Section\AudioCodecResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\AudioCodecResource;
use App\Models\AudioCodec;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
class ListAudioCodecs extends PageList
{
protected static string $resource = AudioCodecResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
protected function getTableQuery(): Builder
{
return AudioCodec::query()->with('search_box')->orderBy('mode', 'asc');
}
}

View File

@@ -1,31 +1,49 @@
<?php
namespace App\Filament\Resources\System\SectionResource\RelationManagers;
namespace App\Filament\Resources\Section;
use App\Filament\Resources\Section\CategoryResource\Pages;
use App\Filament\Resources\Section\CategoryResource\RelationManagers;
use App\Models\Category;
use App\Models\Icon;
use App\Models\SearchBox;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class CategoriesRelationManager extends RelationManager
class CategoryResource extends Resource
{
protected static string $relationship = 'categories';
protected static ?string $model = Category::class;
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $navigationIcon = 'heroicon-o-collection';
protected static function getModelLabel(): string
protected static ?string $navigationGroup = 'Section';
protected static ?int $navigationSort = 2;
protected static function getNavigationLabel(): string
{
return __('label.search_box.category');
return __('admin.sidebar.category');
}
public static function getBreadcrumb(): string
{
return self::getNavigationLabel();
}
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('mode')
->options(SearchBox::query()->pluck('name', 'id')->toArray())
->label(__('label.search_box.label'))
->required()
,
Forms\Components\TextInput::make('name')->required()->label(__('label.search_box.taxonomy.name'))->required(),
Forms\Components\TextInput::make('image')
->label(__('label.search_box.taxonomy.image'))
@@ -46,6 +64,7 @@ class CategoriesRelationManager extends RelationManager
->label(__('label.search_box.taxonomy.sort_index'))
->helperText(__('label.search_box.taxonomy.sort_index_help'))
,
]);
}
@@ -54,31 +73,42 @@ class CategoriesRelationManager extends RelationManager
return $table
->columns([
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('name')->label(__('label.search_box.taxonomy.name')),
Tables\Columns\TextColumn::make('search_box.name')->label(__('label.search_box.label')),
Tables\Columns\TextColumn::make('name')->label(__('label.search_box.taxonomy.name'))->searchable(),
Tables\Columns\TextColumn::make('icon.name')->label(__('label.search_box.taxonomy.icon_id')),
Tables\Columns\TextColumn::make('image')->label(__('label.search_box.taxonomy.image')),
Tables\Columns\TextColumn::make('class_name')->label(__('label.search_box.taxonomy.class_name')),
Tables\Columns\TextColumn::make('sort_index')->label(__('label.search_box.taxonomy.sort_index'))->sortable(),
])
->defaultSort('sort_index')
->defaultSort('sort_index', 'asc')
->filters([
//
])
->headerActions([
Tables\Actions\CreateAction::make()->after(function ($record) {
clear_search_box_cache($record->mode);
}),
Tables\Filters\SelectFilter::make('mode')
->options(SearchBox::query()->pluck('name', 'id')->toArray())
->label(__('label.search_box.label'))
,
])
->actions([
Tables\Actions\EditAction::make()->after(function ($record) {
clear_search_box_cache($record->mode);
}),
Tables\Actions\DeleteAction::make()->after(function ($record) {
clear_search_box_cache($record->mode);
}),
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListCategories::route('/'),
'create' => Pages\CreateCategory::route('/create'),
'edit' => Pages\EditCategory::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\Section\CategoryResource\Pages;
use App\Filament\Resources\Section\CategoryResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateCategory extends CreateRecord
{
protected static string $resource = CategoryResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Section\CategoryResource\Pages;
use App\Filament\Resources\Section\CategoryResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditCategory extends EditRecord
{
protected static string $resource = CategoryResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Filament\Resources\Section\CategoryResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\CategoryResource;
use App\Models\Category;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
class ListCategories extends PageList
{
protected static string $resource = CategoryResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
protected function getTableQuery(): Builder
{
return Category::query()->with('search_box')->orderBy('mode', 'asc');
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace App\Filament\Resources\Section;
use App\Filament\Resources\Section\CodecResource\Pages;
use App\Filament\Resources\Section\CodecResource\RelationManagers;
use App\Models\Codec;
use App\Models\Icon;
use App\Models\SearchBox;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class CodecResource extends Resource
{
protected static ?string $model = Codec::class;
protected static ?string $navigationIcon = 'heroicon-o-bookmark';
protected static ?string $navigationGroup = 'Section';
protected static ?int $navigationSort = 3;
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')->required()->label(__('label.search_box.taxonomy.name'))->required(),
Forms\Components\TextInput::make('sort_index')
->default(0)
->label(__('label.search_box.taxonomy.sort_index'))
->helperText(__('label.search_box.taxonomy.sort_index_help'))
,
Forms\Components\Select::make('mode')
->options(SearchBox::query()->pluck('name', 'id')->toArray())
->label(__('label.search_box.taxonomy.mode'))
->helperText(__('label.search_box.taxonomy.mode_help'))
,
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('search_box.name')
->label(__('label.search_box.label'))
->formatStateUsing(fn ($record) => $record->search_box->name ?? 'All')
,
Tables\Columns\TextColumn::make('name')->label(__('label.search_box.taxonomy.name'))->searchable(),
Tables\Columns\TextColumn::make('sort_index')->label(__('label.search_box.taxonomy.sort_index'))->sortable(),
])
->defaultSort('sort_index', 'asc')
->filters([
Tables\Filters\SelectFilter::make('mode')
->options(SearchBox::query()->pluck('name', 'id')->toArray())
->label(__('label.search_box.taxonomy.mode'))
->query(function (Builder $query, array $data) {
return $query->where(function (Builder $query) use ($data) {
return $query->where('mode', 0)->orWhere('mode', $data['value']);
});
})
,
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListCodecs::route('/'),
'create' => Pages\CreateCodec::route('/create'),
'edit' => Pages\EditCodec::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\Section\CodecResource\Pages;
use App\Filament\Resources\Section\CodecResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateCodec extends CreateRecord
{
protected static string $resource = CodecResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Section\CodecResource\Pages;
use App\Filament\Resources\Section\CodecResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditCodec extends EditRecord
{
protected static string $resource = CodecResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Filament\Resources\Section\CodecResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\CodecResource;
use App\Models\Codec;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
class ListCodecs extends PageList
{
protected static string $resource = CodecResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
protected function getTableQuery(): Builder
{
return Codec::query()->with('search_box')->orderBy('mode', 'asc');
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace App\Filament\Resources\Section;
use App\Filament\OptionsTrait;
use App\Filament\Resources\Section\IconResource\Pages;
use App\Filament\Resources\Section\IconResource\RelationManagers;
use App\Models\Icon;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class IconResource extends Resource
{
use OptionsTrait;
protected static ?string $model = Icon::class;
protected static ?string $navigationIcon = 'heroicon-o-ticket';
protected static ?string $navigationGroup = 'Section';
protected static ?int $navigationSort = 10;
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.icon');
}
public static function getBreadcrumb(): string
{
return self::getNavigationLabel();
}
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->label(__('label.name'))
->required()
,
Forms\Components\TextInput::make('folder')
->label(__('label.icon.folder'))
->required()
->helperText(__('label.icon.folder_help'))
,
Forms\Components\Radio::make('multilang')
->label(__('label.icon.multilang'))
->options(self::$yesOrNo)
->required()
->helperText(__('label.icon.multilang_help'))
,
Forms\Components\Radio::make('secondicon')
->label(__('label.icon.secondicon'))
->options(self::$yesOrNo)
->required()
->helperText(__('label.icon.secondicon_help'))
,
Forms\Components\TextInput::make('cssfile')->label(__('label.icon.cssfile'))->helperText(__('label.icon.cssfile_help')),
Forms\Components\TextInput::make('designer')->label(__('label.icon.designer'))->helperText(__('label.icon.designer_help')),
Forms\Components\Textarea::make('comment')->label(__('label.icon.comment'))->helperText(__('label.icon.comment_help')),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('folder'),
Tables\Columns\TextColumn::make('cssfile'),
Tables\Columns\TextColumn::make('multilang'),
Tables\Columns\TextColumn::make('secondicon'),
Tables\Columns\TextColumn::make('designer'),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListIcons::route('/'),
'create' => Pages\CreateIcon::route('/create'),
'edit' => Pages\EditIcon::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Filament\Resources\Section\IconResource\Pages;
use App\Filament\Resources\Section\IconResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateIcon extends CreateRecord
{
protected static string $view = 'filament.resources.system.category-icon-resource.pages.create-record';
protected static string $resource = IconResource::class;
protected function getViewData(): array
{
return [
'desc' => nexus_trans('label.icon.desc')
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Filament\Resources\Section\IconResource\Pages;
use App\Filament\Resources\Section\IconResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditIcon extends EditRecord
{
protected static string $resource = IconResource::class;
protected static string $view = 'filament.resources.system.category-icon-resource.pages.edit-record';
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
protected function getViewData(): array
{
return [
'desc' => nexus_trans('label.icon.desc')
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\Section\IconResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\IconResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
class ListIcons extends PageList
{
protected static string $resource = IconResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Filament\Resources\Section;
use App\Filament\Resources\Section\MediaResource\Pages;
use App\Filament\Resources\Section\MediaResource\RelationManagers;
use App\Models\Media;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class MediaResource extends CodecResource
{
protected static ?string $model = Media::class;
protected static ?int $navigationSort = 8;
public static function form(Form $form): Form
{
return parent::form($form);
}
public static function table(Table $table): Table
{
return parent::table($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListMedia::route('/'),
'create' => Pages\CreateMedia::route('/create'),
'edit' => Pages\EditMedia::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\Section\MediaResource\Pages;
use App\Filament\Resources\Section\MediaResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateMedia extends CreateRecord
{
protected static string $resource = MediaResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Section\MediaResource\Pages;
use App\Filament\Resources\Section\MediaResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditMedia extends EditRecord
{
protected static string $resource = MediaResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Filament\Resources\Section\MediaResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\MediaResource;
use App\Models\Media;
use App\Models\Source;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
class ListMedia extends PageList
{
protected static string $resource = MediaResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
protected function getTableQuery(): Builder
{
return Media::query()->with('search_box')->orderBy('mode', 'asc');
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Filament\Resources\Section;
use App\Filament\Resources\Section\ProcessingResource\Pages;
use App\Filament\Resources\Section\ProcessingResource\RelationManagers;
use App\Models\Processing;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class ProcessingResource extends CodecResource
{
protected static ?string $model = Processing::class;
protected static ?int $navigationSort = 9;
public static function form(Form $form): Form
{
return parent::form($form);
}
public static function table(Table $table): Table
{
return parent::table($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListProcessings::route('/'),
'create' => Pages\CreateProcessing::route('/create'),
'edit' => Pages\EditProcessing::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\Section\ProcessingResource\Pages;
use App\Filament\Resources\Section\ProcessingResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateProcessing extends CreateRecord
{
protected static string $resource = ProcessingResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Section\ProcessingResource\Pages;
use App\Filament\Resources\Section\ProcessingResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditProcessing extends EditRecord
{
protected static string $resource = ProcessingResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Filament\Resources\Section\ProcessingResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\ProcessingResource;
use App\Models\Processing;
use App\Models\Source;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
class ListProcessings extends PageList
{
protected static string $resource = ProcessingResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
protected function getTableQuery(): Builder
{
return Processing::query()->with('search_box')->orderBy('mode', 'asc');
}
}

View File

@@ -0,0 +1,144 @@
<?php
namespace App\Filament\Resources\Section;
use App\Filament\Resources\Section\SecondIconResource\Pages;
use App\Filament\Resources\Section\SecondIconResource\RelationManagers;
use App\Models\SearchBox;
use App\Models\SecondIcon;
use App\Models\Setting;
use App\Repositories\SearchBoxRepository;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Nexus\Database\NexusDB;
class SecondIconResource extends Resource
{
protected static ?string $model = SecondIcon::class;
protected static ?string $navigationIcon = 'heroicon-o-ticket';
protected static ?string $navigationGroup = 'Section';
protected static ?int $navigationSort = 11;
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.second_icon');
}
public static function getBreadcrumb(): string
{
return self::getNavigationLabel();
}
public static function form(Form $form): Form
{
$searchBoxRep = new SearchBoxRepository();
$torrentMode = Setting::get('main.browsecat');
$specialMode = Setting::get('main.specialcat');
$torrentTaxonomySchema = $searchBoxRep->listTaxonomyFormSchema($torrentMode);
$specialTaxonomySchema = $searchBoxRep->listTaxonomyFormSchema($specialMode);
$modeOptions = SearchBox::query()->whereIn('id', [$torrentMode, $specialMode])->pluck('name', 'id')->toArray();
return $form
->schema([
Forms\Components\TextInput::make('name')
->label(__('label.name'))
->required()
->helperText(__('label.second_icon.name_help'))
,
Forms\Components\Select::make('mode')
->label(__('label.search_box.label'))
->options($modeOptions)
->required()
->reactive()
,
Forms\Components\TextInput::make('image')
->label(__('label.second_icon.image'))
->required()
->helperText(__('label.second_icon.image_help'))
,
Forms\Components\TextInput::make('class_name')
->label(__('label.second_icon.class_name'))
->helperText(__('label.second_icon.class_name_help'))
,
Forms\Components\Section::make(__('label.second_icon.select_section'))
->id("taxonomy_$torrentMode")
->schema($torrentTaxonomySchema)
->columns(4)
->hidden(fn (\Closure $get) => $get('mode') != $torrentMode)
,
Forms\Components\Section::make(__('label.second_icon.select_section'))
->id("taxonomy_$specialMode")
->schema($specialTaxonomySchema)
->columns(4)
->hidden(fn (\Closure $get) => $get('mode') != $specialMode)
,
]);
}
public static function table(Table $table): Table
{
$columns = [
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('search_box.name')
->label(__('label.search_box.label'))
->formatStateUsing(fn ($record) => $record->search_box->name ?? 'All')
,
Tables\Columns\TextColumn::make('name')->label(__('label.name')),
Tables\Columns\TextColumn::make('image')->label(__('label.second_icon.image')),
Tables\Columns\TextColumn::make('class_name')->label(__('label.second_icon.class_name')),
];
$taxonomyList = self::listTaxonomy();
foreach (SearchBox::$taxonomies as $torrentField => $tableName) {
$columns[] = Tables\Columns\TextColumn::make($torrentField)->formatStateUsing(function ($state) use ($taxonomyList, $torrentField) {
return $taxonomyList[$torrentField]->get($state);
});
}
return $table
->columns($columns)
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
private static function listTaxonomy()
{
static $taxonomyList = [];
if (empty($taxonomyList)) {
foreach (SearchBox::$taxonomies as $torrentField => $tableName) {
$taxonomyList[$torrentField] = NexusDB::table($tableName)->pluck('name', 'id');
}
}
return $taxonomyList;
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListSecondIcons::route('/'),
'create' => Pages\CreateSecondIcon::route('/create'),
'edit' => Pages\EditSecondIcon::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Section\SecondIconResource\Pages;
use App\Filament\Resources\Section\SecondIconResource;
use App\Models\SearchBox;
use App\Models\SecondIcon;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateSecondIcon extends CreateRecord
{
protected static string $resource = SecondIconResource::class;
protected function mutateFormDataBeforeCreate(array $data): array
{
return SecondIcon::formatFormData($data);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Filament\Resources\Section\SecondIconResource\Pages;
use App\Filament\Resources\Section\SecondIconResource;
use App\Models\SearchBox;
use App\Models\SecondIcon;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditSecondIcon extends EditRecord
{
protected static string $resource = SecondIconResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
protected function mutateFormDataBeforeSave(array $data): array
{
return SecondIcon::formatFormData($data);
}
protected function mutateFormDataBeforeFill(array $data): array
{
$mode = $data['mode'];
foreach (SearchBox::$taxonomies as $torrentField => $table) {
$taxonomyValue = $data[$torrentField] ?? null;
unset($data[$torrentField]);
$data[$torrentField][$mode] = $taxonomyValue;
}
return $data;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Filament\Resources\Section\SecondIconResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\SecondIconResource;
use App\Models\SecondIcon;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
class ListSecondIcons extends PageList
{
protected static string $resource = SecondIconResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
protected function getTableQuery(): Builder
{
return SecondIcon::query()->with('search_box');
}
}

View File

@@ -1,9 +1,10 @@
<?php
namespace App\Filament\Resources\System;
namespace App\Filament\Resources\Section;
use App\Filament\Resources\System\SectionResource\Pages;
use App\Filament\Resources\System\SectionResource\RelationManagers;
use App\Http\Middleware\Locale;
use App\Models\Forum;
use App\Models\SearchBox;
use App\Models\TorrentCustomField;
@@ -27,9 +28,9 @@ class SectionResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-view-boards';
protected static ?string $navigationGroup = 'System';
protected static ?string $navigationGroup = 'Section';
protected static ?int $navigationSort = 2;
protected static ?int $navigationSort = 1;
protected static function getNavigationLabel(): string
{
@@ -41,11 +42,26 @@ class SectionResource extends Resource
return self::getNavigationLabel();
}
private static function buildLocalSchema($name)
{
$localeSchema = [];
foreach (Locale::$languageMaps as $lang => $locale) {
$localeSchema[] = Forms\Components\TextInput::make("$name.$lang")->required()->label($lang);
}
return $localeSchema;
}
public static function form(Form $form): Form
{
$displayTextLocalSchema = self::buildLocalSchema('display_text');
$sectionNameLocalSchema = self::buildLocalSchema('section_name');
return $form
->schema([
Forms\Components\TextInput::make('name')->label(__('label.search_box.name'))->rules('alpha_dash')->required(),
Forms\Components\TextInput::make('name')
->label(__('label.search_box.name'))
->rules('alpha_dash')
->required()
,
Forms\Components\TextInput::make('catsperrow')
->label(__('label.search_box.catsperrow'))
->helperText(__('label.search_box.catsperrow_help'))
@@ -60,10 +76,6 @@ class SectionResource extends Resource
->required()
->default(3)
,
Forms\Components\TextInput::make('section_name')
->label(__('label.search_box.section_name'))
->helperText(__('label.search_box.section_name_help'))
,
Forms\Components\CheckboxList::make('custom_fields')
->options(TorrentCustomField::getCheckboxOptions())
->label(__('label.search_box.custom_fields'))
@@ -74,20 +86,19 @@ class SectionResource extends Resource
Forms\Components\Textarea::make('custom_fields_display')
->label(__('label.search_box.custom_fields_display'))
->helperText(__('label.search_box.custom_fields_display_help'))
->columnSpan(['sm' => 'full'])
,
Forms\Components\Toggle::make('is_default')
->label(__('label.search_box.is_default'))
->columnSpan(['sm' => 'full'])
Forms\Components\Section::make(__('label.search_box.section_name'))
->schema($sectionNameLocalSchema)
->columns(count($sectionNameLocalSchema))
,
Forms\Components\Toggle::make('showsubcat')->label(__('label.search_box.showsubcat')),
Forms\Components\Toggle::make('showsubcat')->label(__('label.search_box.showsubcat'))->columnSpan(['sm' => 'full']),
Forms\Components\Section::make(__('label.search_box.showsubcat'))->schema([
Forms\Components\Repeater::make('extra.' . SearchBox::EXTRA_TAXONOMY_LABELS)
->schema([
Forms\Components\Select::make('torrent_field')->options(SearchBox::getSubCatOptions())->label(__('label.search_box.torrent_field')),
Forms\Components\TextInput::make('display_text')->label(__('label.search_box.taxonomy_display_text')),
Forms\Components\Section::make(__('label.search_box.taxonomy_display_text'))->schema($displayTextLocalSchema)->columns(count($displayTextLocalSchema)),
])
->label(__('label.search_box.taxonomies'))->columns(2)
->label(__('label.search_box.taxonomies'))
->rules([
function () {
return function (string $attribute, $value, \Closure $fail) {
@@ -104,7 +115,7 @@ class SectionResource extends Resource
])
,
]),
])->columns(3);
]);
}
public static function table(Table $table): Table
@@ -113,8 +124,6 @@ class SectionResource extends Resource
->columns([
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('name')->label(__('label.search_box.name')),
Tables\Columns\TextColumn::make('section_name')->label(__('label.search_box.section_name')),
Tables\Columns\BooleanColumn::make('is_default')->label(__('label.search_box.is_default')),
Tables\Columns\BooleanColumn::make('showsubcat')->label(__('label.search_box.showsubcat')),
Tables\Columns\BooleanColumn::make('showsource'),
Tables\Columns\BooleanColumn::make('showmedium'),
@@ -139,14 +148,7 @@ class SectionResource extends Resource
public static function getRelations(): array
{
return [
RelationManagers\CategoriesRelationManager::class,
RelationManagers\TaxonomySourcesRelationManager::class,
RelationManagers\TaxonomyMediumRelationManager::class,
RelationManagers\TaxonomyCodecsRelationManager::class,
RelationManagers\TaxonomyAudioCodecsRelationManager::class,
RelationManagers\TaxonomyTeamsRelationManager::class,
RelationManagers\TaxonomyStandardsRelationManager::class,
RelationManagers\TaxonomyProcessingRelationManager::class,
];
}

View File

@@ -2,7 +2,7 @@
namespace App\Filament\Resources\System\SectionResource\Pages;
use App\Filament\Resources\System\SectionResource;
use App\Filament\Resources\Section\SectionResource;
use App\Models\SearchBox;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;

View File

@@ -2,7 +2,7 @@
namespace App\Filament\Resources\System\SectionResource\Pages;
use App\Filament\Resources\System\SectionResource;
use App\Filament\Resources\Section\SectionResource;
use App\Models\SearchBox;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;

View File

@@ -3,7 +3,7 @@
namespace App\Filament\Resources\System\SectionResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\System\SectionResource;
use App\Filament\Resources\Section\SectionResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Filament\Resources\Section;
use App\Filament\Resources\Section\SourceResource\Pages;
use App\Filament\Resources\Section\SourceResource\RelationManagers;
use App\Models\Source;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class SourceResource extends CodecResource
{
protected static ?string $model = Source::class;
protected static ?int $navigationSort = 7;
public static function form(Form $form): Form
{
return parent::form($form);
}
public static function table(Table $table): Table
{
return parent::table($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListSources::route('/'),
'create' => Pages\CreateSource::route('/create'),
'edit' => Pages\EditSource::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\Section\SourceResource\Pages;
use App\Filament\Resources\Section\SourceResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateSource extends CreateRecord
{
protected static string $resource = SourceResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Section\SourceResource\Pages;
use App\Filament\Resources\Section\SourceResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditSource extends EditRecord
{
protected static string $resource = SourceResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Filament\Resources\Section\SourceResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\SourceResource;
use App\Models\Source;
use App\Models\Team;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
class ListSources extends PageList
{
protected static string $resource = SourceResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
protected function getTableQuery(): Builder
{
return Source::query()->with('search_box')->orderBy('mode', 'asc');
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Filament\Resources\Section;
use App\Filament\Resources\Section\StandardResource\Pages;
use App\Filament\Resources\Section\StandardResource\RelationManagers;
use App\Models\Standard;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class StandardResource extends CodecResource
{
protected static ?string $model = Standard::class;
protected static ?int $navigationSort = 5;
public static function form(Form $form): Form
{
return parent::form($form);
}
public static function table(Table $table): Table
{
return parent::table($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListStandards::route('/'),
'create' => Pages\CreateStandard::route('/create'),
'edit' => Pages\EditStandard::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\Section\StandardResource\Pages;
use App\Filament\Resources\Section\StandardResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateStandard extends CreateRecord
{
protected static string $resource = StandardResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Section\StandardResource\Pages;
use App\Filament\Resources\Section\StandardResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditStandard extends EditRecord
{
protected static string $resource = StandardResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Filament\Resources\Section\StandardResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\StandardResource;
use App\Models\Codec;
use App\Models\Standard;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
class ListStandards extends PageList
{
protected static string $resource = StandardResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
protected function getTableQuery(): Builder
{
return Standard::query()->with('search_box')->orderBy('mode', 'asc');
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Filament\Resources\Section;
use App\Filament\Resources\Section\TeamResource\Pages;
use App\Filament\Resources\Section\TeamResource\RelationManagers;
use App\Models\Team;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class TeamResource extends CodecResource
{
protected static ?string $model = Team::class;
protected static ?int $navigationSort = 6;
public static function form(Form $form): Form
{
return parent::form($form);
}
public static function table(Table $table): Table
{
return parent::table($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListTeams::route('/'),
'create' => Pages\CreateTeam::route('/create'),
'edit' => Pages\EditTeam::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\Section\TeamResource\Pages;
use App\Filament\Resources\Section\TeamResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateTeam extends CreateRecord
{
protected static string $resource = TeamResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Section\TeamResource\Pages;
use App\Filament\Resources\Section\TeamResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditTeam extends EditRecord
{
protected static string $resource = TeamResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Filament\Resources\Section\TeamResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Section\TeamResource;
use App\Models\Standard;
use App\Models\Team;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
class ListTeams extends PageList
{
protected static string $resource = TeamResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
protected function getTableQuery(): Builder
{
return Team::query()->with('search_box')->orderBy('mode', 'asc');
}
}

View File

@@ -24,8 +24,6 @@ class PluginResource extends Resource
protected static ?int $navigationSort = 99;
protected static bool $shouldRegisterNavigation = false;
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.plugin');

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Filament\Resources\System\SectionResource\RelationManagers;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class TaxonomyAudioCodecsRelationManager extends TaxonomySourcesRelationManager
{
protected static string $relationship = 'taxonomy_audiocodec';
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $torrentField = 'audiocodec';
}

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Filament\Resources\System\SectionResource\RelationManagers;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class TaxonomyCodecsRelationManager extends TaxonomySourcesRelationManager
{
protected static string $relationship = 'taxonomy_codec';
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $torrentField = 'codec';
}

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Filament\Resources\System\SectionResource\RelationManagers;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class TaxonomyMediumRelationManager extends TaxonomySourcesRelationManager
{
protected static string $relationship = 'taxonomy_medium';
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $torrentField = 'medium';
}

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Filament\Resources\System\SectionResource\RelationManagers;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class TaxonomyProcessingRelationManager extends TaxonomySourcesRelationManager
{
protected static string $relationship = 'taxonomy_processing';
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $torrentField = 'processing';
}

View File

@@ -1,114 +0,0 @@
<?php
namespace App\Filament\Resources\System\SectionResource\RelationManagers;
use App\Filament\Resources\System\SectionResource\TaxonomyTrait;
use App\Models\SearchBox;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class TaxonomySourcesRelationManager extends RelationManager
{
protected static string $relationship = 'taxonomy_source';
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $torrentField = 'source';
protected static function getModelLabel(): string
{
static $taxonomies;
if (!$taxonomies) {
$params = request()->all();
$taxonomies = $params['serverMemo']['data']['data']['extra'][SearchBox::EXTRA_TAXONOMY_LABELS] ?? [];
if (empty($taxonomies)) {
$id = request()->route()->parameter('record');
if (!$id) {
$id = $params['serverMemo']['dataMeta']['models']['ownerRecord']['id'] ?? null;
}
do_log("searchBox ID: $id");
$searchBox = SearchBox::query()->find($id);
if ($searchBox) {
$taxonomies = $searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS] ?? [];
} else {
$taxonomies = [];
}
}
}
foreach ($taxonomies as $taxonomy) {
if ($taxonomy['torrent_field'] == static::$torrentField) {
return $taxonomy['display_text'];
}
}
$field = static::$torrentField;
return __("label.search_box.$field") ?? $field;
}
public static function shouldShowTaxonomy(SearchBox $searchBox): bool
{
$taxonomies = $searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS] ?? [];
foreach ($taxonomies as $taxonomy) {
if ($taxonomy['torrent_field'] == static::$torrentField) {
do_log("torrent_field: " . static::$torrentField . " should show");
return true;
}
}
do_log("torrent_field: " . static::$torrentField . " don't show");
return false;
}
public static function canViewForRecord(Model $ownerRecord): bool
{
return self::shouldShowTaxonomy($ownerRecord);
}
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')->required(),
Forms\Components\TextInput::make('sort_index')
->default(0)
->label(__('label.search_box.taxonomy.sort_index'))
->helperText(__('label.search_box.taxonomy.sort_index_help'))
,
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('name')->label(__('label.search_box.taxonomy.name')),
Tables\Columns\TextColumn::make('sort_index')->label(__('label.search_box.taxonomy.sort_index'))->sortable(),
])
->defaultSort('sort_index')
->filters([
//
])
->headerActions([
Tables\Actions\CreateAction::make()->after(function ($record) {
clear_search_box_cache($record->mode);
}),
])
->actions([
Tables\Actions\EditAction::make()->after(function ($record) {
clear_search_box_cache($record->mode);
}),
Tables\Actions\DeleteAction::make()->after(function ($record) {
clear_search_box_cache($record->mode);
}),
])
->bulkActions([
]);
}
}

View File

@@ -1,21 +0,0 @@
<?php
namespace App\Filament\Resources\System\SectionResource\RelationManagers;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class TaxonomyStandardsRelationManager extends TaxonomySourcesRelationManager
{
protected static string $relationship = 'taxonomy_standard';
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $torrentField = 'standard';
}

View File

@@ -1,21 +0,0 @@
<?php
namespace App\Filament\Resources\System\SectionResource\RelationManagers;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class TaxonomyTeamsRelationManager extends TaxonomySourcesRelationManager
{
protected static string $relationship = 'taxonomy_team';
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $torrentField = 'team';
}

View File

@@ -13,4 +13,9 @@ class AudioCodec extends NexusModel
{
return nexus_trans('searchbox.sub_category_audio_codec_label');
}
public function search_box()
{
return $this->belongsTo(SearchBox::class, 'mode', 'id');
}
}

View File

@@ -18,4 +18,9 @@ class Category extends NexusModel
{
return $this->belongsTo(Icon::class, 'icon_id');
}
public function search_box()
{
return $this->belongsTo(SearchBox::class, 'mode', 'id');
}
}

View File

@@ -13,4 +13,9 @@ class Codec extends NexusModel
{
return nexus_trans('searchbox.sub_category_codec_label');
}
public function search_box()
{
return $this->belongsTo(SearchBox::class, 'mode', 'id');
}
}

View File

@@ -13,4 +13,9 @@ class Media extends NexusModel
{
return nexus_trans('searchbox.sub_category_media_label');
}
public function search_box()
{
return $this->belongsTo(SearchBox::class, 'mode', 'id');
}
}

View File

@@ -13,4 +13,9 @@ class Processing extends NexusModel
{
return nexus_trans('searchbox.sub_category_processing_label');
}
public function search_box()
{
return $this->belongsTo(SearchBox::class, 'mode', 'id');
}
}

View File

@@ -3,10 +3,14 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Str;
use Nexus\Database\NexusDB;
class SearchBox extends NexusModel
{
private static array $instances = [];
protected $table = 'searchbox';
protected $fillable = [
@@ -21,6 +25,7 @@ class SearchBox extends NexusModel
'extra' => 'array',
'is_default' => 'boolean',
'showsubcat' => 'boolean',
'section_name' => 'json',
];
const EXTRA_TAXONOMY_LABELS = 'taxonomy_labels';
@@ -40,9 +45,9 @@ class SearchBox extends NexusModel
'medium' => 'media',
'codec' => 'codecs',
'audiocodec' => 'audiocodecs',
'team' => 'teams',
'standard' => 'standards',
'processing' => 'processings'
'processing' => 'processings',
'team' => 'teams',
];
public static array $extras = [
@@ -66,21 +71,23 @@ class SearchBox extends NexusModel
foreach ($data['extra'][self::EXTRA_TAXONOMY_LABELS] ?? [] as $item) {
if ($field == $item['torrent_field']) {
$data["show{$field}"] = 1;
$data["extra->" . self::EXTRA_TAXONOMY_LABELS][] = $item;
// $data["extra->" . self::EXTRA_TAXONOMY_LABELS][] = $item;
}
}
}
$data["extra->" . self::EXTRA_TAXONOMY_LABELS] = $data['extra'][self::EXTRA_TAXONOMY_LABELS];
return $data;
}
public function getTaxonomyLabel($torrentField)
{
$lang = get_langfolder_cookie();
foreach ($this->extra[self::EXTRA_TAXONOMY_LABELS] ?? [] as $item) {
if ($item['torrent_field'] == $torrentField) {
return $item['display_text'];
return $item['display_text'][$lang] ?? 'Unknown';
}
}
return nexus_trans('label.torrent.' . $torrentField) ?: ucfirst($torrentField);
return nexus_trans("searchbox.sub_category_{$torrentField}_label") ?: ucfirst($torrentField);
}
protected function customFields(): Attribute
@@ -111,6 +118,25 @@ class SearchBox extends NexusModel
return $result;
}
public static function get(int $id)
{
if (!isset(self::$instances[$id])) {
self::$instances[$id] = self::query()->find($id);
}
return self::$instances[$id];
}
public static function listTaxonomyItems($searchBox, $torrentField): \Illuminate\Support\Collection
{
if (!$searchBox instanceof self) {
$searchBox = self::get(intval($searchBox));
}
$table = self::$taxonomies[$torrentField];
return NexusDB::table($table)->where(function (Builder $query) use ($searchBox) {
return $query->where('mode', $searchBox->id)->orWhere('mode', 0);
})->get();
}
public function getCustomFieldsAttribute($value): array
{
if (!is_array($value)) {

32
app/Models/SecondIcon.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
namespace App\Models;
class SecondIcon extends NexusModel
{
protected $table = 'secondicons';
protected $fillable = [
'name', 'class_name', 'image', 'mode',
'source', 'medium', 'codec', 'audiocodec', 'standard', 'processing', 'team'
];
public static function formatFormData(array $data): array
{
foreach (SearchBox::$taxonomies as $torrentField => $table) {
$mode = $data['mode'];
if (empty($data[$torrentField][$mode])) {
unset($data[$torrentField]);
} else {
$data[$torrentField] = $data[$torrentField][$mode];
}
}
return $data;
}
public function search_box()
{
return $this->belongsTo(SearchBox::class, 'mode', 'id');
}
}

View File

@@ -11,4 +11,9 @@ class Source extends NexusModel
{
return nexus_trans('searchbox.sub_category_source_label');
}
public function search_box()
{
return $this->belongsTo(SearchBox::class, 'mode', 'id');
}
}

View File

@@ -11,4 +11,9 @@ class Standard extends NexusModel
{
return nexus_trans('searchbox.sub_category_standard_label');
}
public function search_box()
{
return $this->belongsTo(SearchBox::class, 'mode', 'id');
}
}

View File

@@ -11,4 +11,9 @@ class Team extends NexusModel
{
return nexus_trans('searchbox.sub_category_team_label');
}
public function search_box()
{
return $this->belongsTo(SearchBox::class, 'mode', 'id');
}
}

View File

@@ -2,23 +2,16 @@
namespace App\Models;
<<<<<<< HEAD
=======
use Nexus\Database\NexusDB;
>>>>>>> php8
class TorrentCustomFieldValue extends NexusModel
{
protected $table = 'torrents_custom_field_values';
<<<<<<< HEAD
protected $fillable = [
'torrent_id', 'custom_field_id', 'custom_field_value',
];
=======
public $timestamps = true;
protected $fillable = ['torrent_id', 'custom_field_id', 'custom_field_value', ];
>>>>>>> php8
}

View File

@@ -40,6 +40,7 @@ class AppServiceProvider extends ServiceProvider
'User',
'Torrent',
'Other',
'Section',
'System',
]);
});

View File

@@ -2,14 +2,18 @@
namespace App\Repositories;
use App\Http\Middleware\Locale;
use App\Models\Icon;
use App\Models\NexusModel;
use App\Models\SearchBox;
use App\Models\SearchBoxField;
use App\Models\SecondIcon;
use App\Models\Setting;
use Elasticsearch\Endpoints\Search;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Arr;
use Nexus\Database\NexusDB;
use Filament\Forms;
class SearchBoxRepository extends BaseRepository
{
@@ -103,6 +107,8 @@ class SearchBoxRepository extends BaseRepository
return Icon::query()->find(array_keys($iconIdArr));
}
/**
*/
public function migrateToModeRelated()
{
$secondIconTable = 'secondicons';
@@ -112,25 +118,25 @@ class SearchBoxRepository extends BaseRepository
$tables = array_values(SearchBox::$taxonomies);
foreach ($searchBoxList as $searchBox) {
if ($searchBox->id == $normalId) {
//all sub categories add `mode` field
foreach ($tables as $table) {
NexusDB::table($table)->update(['mode' => $normalId]);
do_log("update table $table mode = $normalId");
}
//also second icons
NexusDB::table($secondIconTable)->update(['mode' => $normalId]);
do_log("update table $secondIconTable mode = $normalId");
} elseif ($searchBox->id == $specialId && $specialId != $normalId) {
//copy from normal section
foreach ($tables as $table) {
$sql = sprintf(
"insert into `%s` (name, sort_index, mode) select name, sort_index, '%s' from `%s`",
$table, $specialId, $table
);
NexusDB::statement($sql);
do_log("copy table $table, $sql");
}
// if ($searchBox->id == $normalId) {
// //all sub categories add `mode` field
// foreach ($tables as $table) {
// NexusDB::table($table)->update(['mode' => $normalId]);
// do_log("update table $table mode = $normalId");
// }
// //also second icons
// NexusDB::table($secondIconTable)->update(['mode' => $normalId]);
// do_log("update table $secondIconTable mode = $normalId");
// } elseif ($searchBox->id == $specialId && $specialId != $normalId) {
// //copy from normal section
// foreach ($tables as $table) {
// $sql = sprintf(
// "insert into `%s` (name, sort_index, mode) select name, sort_index, '%s' from `%s`",
// $table, $specialId, $table
// );
// NexusDB::statement($sql);
// do_log("copy table $table, $sql");
// }
// $fields = array_keys(SearchBox::$taxonomies);
// $fields = array_merge($fields, ['name', 'class_name', 'image']);
// $fieldStr = implode(', ', $fields);
@@ -140,47 +146,152 @@ class SearchBoxRepository extends BaseRepository
// );
// NexusDB::statement($sql);
// do_log("copy table $secondIconTable, $sql");
}
// }
$taxonomies = [];
foreach (SearchBox::$taxonomies as $field => $taxonomyTable) {
$showField = "show" . $field;
if ($searchBox->{$showField}) {
foreach (SearchBox::$taxonomies as $torrentField => $taxonomyTable) {
$searchBoxField = "show" . $torrentField;
if ($searchBox->showsubcat && $searchBox->{$searchBoxField}) {
$taxonomies[] = [
'torrent_field' => $field,
'display_text' => $field,
'torrent_field' => $torrentField,
'display_text' => [
'en' => nexus_trans("searchbox.sub_category_{$torrentField}_label", [], Locale::$languageMaps['en']),
'chs' => nexus_trans("searchbox.sub_category_{$torrentField}_label", [], Locale::$languageMaps['chs']),
'cht' => nexus_trans("searchbox.sub_category_{$torrentField}_label", [], Locale::$languageMaps['cht']),
],
];
}
}
$searchBox->update(["extra->" . SearchBox::EXTRA_TAXONOMY_LABELS => $taxonomies]);
if (!empty($taxonomies)) {
$searchBox->update(["extra->" . SearchBox::EXTRA_TAXONOMY_LABELS => $taxonomies]);
}
}
}
public function renderQualitySelect($searchBox, array $torrentInfo = []): string
public function renderTaxonomySelect($searchBox, array $torrentInfo = []): string
{
if (!$searchBox instanceof SearchBox) {
$searchBox = SearchBox::query()->findOrFail(intval($searchBox));
$searchBox = SearchBox::get(intval($searchBox));
}
$results = [];
foreach (SearchBox::$taxonomies as $torrentField => $table) {
$searchBoxField = "show" . $torrentField;
if ($searchBox->{$searchBoxField}) {
$select = sprintf("<b>%s:</b>", $searchBox->getTaxonomyLabel($torrentField));
$select .= sprintf('<select name="%s" data-mode="%s">', $torrentField . "_sel", $searchBox->id);
$select .= sprintf('<option value="%s">%s</option>', 0, nexus_trans('nexus.select_one_please'));
$relation = "taxonomy_$torrentField";
$list = $searchBox->{$relation};
foreach ($list as $item) {
$selected = '';
if (isset($torrentInfo[$torrentField]) && $torrentInfo[$torrentField] == $item->id) {
$selected = " selected";
}
$select .= sprintf('<option value="%s"%s>%s</option>', $item->id, $selected, $item->name);
//Keep the order
if (!empty($searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS])) {
foreach ($searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS] as $taxonomy) {
$select = $this->buildTaxonomySelect($searchBox, $taxonomy['torrent_field'], $torrentInfo);
if ($select) {
$results[] = $select;
}
}
} else {
foreach (SearchBox::$taxonomies as $torrentField => $table) {
$select = $this->buildTaxonomySelect($searchBox, $torrentField, $torrentInfo);
if ($select) {
$results[] = $select;
}
$select .= '</select>';
$results[] = $select;
}
}
return implode('&nbsp;&nbsp;', $results);
}
public function listTaxonomyInfo($searchBox, array $torrentWithTaxonomy): array
{
if (!$searchBox instanceof SearchBox) {
$searchBox = SearchBox::get(intval($searchBox));
}
$results = [];
//Keep the order
if (!empty($searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS])) {
foreach ($searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS] as $item) {
$taxonomy = $this->getTaxonomyInfo($searchBox, $torrentWithTaxonomy, $item['torrent_field']);
if ($taxonomy) {
$results[] = $taxonomy;
}
}
} else {
foreach (SearchBox::$taxonomies as $torrentField => $table) {
$taxonomy = $this->getTaxonomyInfo($searchBox, $torrentWithTaxonomy, $torrentField);
if ($taxonomy) {
$results[] = $taxonomy;
}
}
}
return $results;
}
private function getTaxonomyInfo(SearchBox $searchBox, array $torrentWithTaxonomy, $torrentField)
{
$searchBoxField = "show" . $torrentField;
$torrentTaxonomyField = $torrentField . "_name";
if ($searchBox->showsubcat && $searchBox->{$searchBoxField} && !empty($torrentWithTaxonomy[$torrentTaxonomyField])) {
return [
'field' => $torrentField,
'label' => $searchBox->getTaxonomyLabel($torrentField),
'value' => $torrentWithTaxonomy[$torrentTaxonomyField],
];
}
}
private function buildTaxonomySelect(SearchBox $searchBox, $torrentField, array $torrentInfo)
{
$searchBoxId = $searchBox->id;
$searchBoxField = "show" . $torrentField;
if ($searchBox->showsubcat && $searchBox->{$searchBoxField}) {
$table = SearchBox::$taxonomies[$torrentField];
$select = sprintf("<b>%s: </b>", $searchBox->getTaxonomyLabel($torrentField));
$select .= sprintf('<select name="%s_sel[%s]" data-mode="%s_%s">',$torrentField, $searchBoxId, $torrentField, $searchBoxId);
$select .= sprintf('<option value="%s">%s</option>', 0, nexus_trans('nexus.select_one_please'));
$list = NexusDB::table($table)->where(function (Builder $query) use ($searchBox) {
return $query->where('mode', $searchBox->id)->orWhere('mode', 0);
})->get();
foreach ($list as $item) {
$selected = '';
if (isset($torrentInfo[$torrentField]) && $torrentInfo[$torrentField] == $item->id) {
$selected = " selected";
}
$select .= sprintf('<option value="%s"%s>%s</option>', $item->id, $selected, $item->name);
}
$select .= '</select>';
return $select;
}
}
public function listTaxonomyFormSchema($searchBox): array
{
if (!$searchBox instanceof SearchBox) {
$searchBox = SearchBox::get(intval($searchBox));
}
$results = [];
//Keep the order
if (!empty($searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS])) {
foreach ($searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS] as $taxonomy) {
$select = $this->buildTaxonomyFormSchema($searchBox, $taxonomy['torrent_field']);
if ($select) {
$results[] = $select;
}
}
} else {
foreach (SearchBox::$taxonomies as $torrentField => $table) {
$select = $this->buildTaxonomyFormSchema($searchBox, $torrentField);
if ($select) {
$results[] = $select;
}
}
}
return $results;
}
private function buildTaxonomyFormSchema(SearchBox $searchBox, $torrentField)
{
$searchBoxId = $searchBox->id;
$searchBoxField = "show" . $torrentField;
$name = sprintf('%s.%s', $torrentField, $searchBoxId);
if ($searchBox->showsubcat && $searchBox->{$searchBoxField}) {
$items = SearchBox::listTaxonomyItems($searchBox, $torrentField);
return Forms\Components\Select::make($name)
->options($items->pluck('name', 'id')->toArray())
->label($searchBox->getTaxonomyLabel($torrentField));
}
}
}

View File

@@ -32,9 +32,10 @@
"ext-redis": "*",
"ext-xml": "*",
"ext-gmp": "*",
"ext-zend-opcache": "*",
"doctrine/dbal": "^3.1",
"elasticsearch/elasticsearch": "^7.16",
"filament/filament": "2.14.2",
"filament/filament": "2.16.36",
"flowframe/laravel-trend": "^0.1.1",
"fruitcake/laravel-cors": "^2.0",
"geoip2/geoip2": "~2.0",

2141
composer.lock generated

File diff suppressed because it is too large Load Diff

51
config/notifications.php Normal file
View File

@@ -0,0 +1,51 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Dark mode
|--------------------------------------------------------------------------
|
| By enabling this setting, your notifications will be ready for Tailwind's
| Dark Mode feature.
|
| https://tailwindcss.com/docs/dark-mode
|
*/
'dark_mode' => false,
/*
|--------------------------------------------------------------------------
| Database notifications
|--------------------------------------------------------------------------
|
| By enabling this feature, your users are able to open a slide-over within
| the app to view their database notifications.
|
*/
'database' => [
'enabled' => false,
'trigger' => null,
'polling_interval' => '30s',
],
/*
|--------------------------------------------------------------------------
| Layout
|--------------------------------------------------------------------------
|
| This is the configuration for the general layout of notifications.
|
*/
'layout' => [
'alignment' => [
'horizontal' => 'right',
'vertical' => 'top',
],
],
];

View File

@@ -53,6 +53,7 @@ return [
'pagination' => [
'default_records_per_page' => 10,
'records_per_page_select_options' => [10, 50, 100, 200],
],
/*

View File

@@ -14,8 +14,7 @@ return new class extends Migration
public function up()
{
Schema::table('searchbox', function (Blueprint $table) {
$table->string('section_name')->after('name')->default('');
$table->integer('is_default')->after('section_name')->default(0);
$table->json('section_name')->after('name')->nullable(true);
});
}
@@ -27,7 +26,7 @@ return new class extends Migration
public function down()
{
Schema::table('searchbox', function (Blueprint $table) {
$table->dropColumn('section_name', 'is_default');
$table->dropColumn('section_name');
});
}
};

View File

@@ -22,6 +22,12 @@ return new class extends Migration
$table->string('class_name')->nullable(true)->default('')->change();
$table->string('image')->nullable(true)->default('')->change();
});
Schema::table('caticons', function (Blueprint $table) {
$table->string('cssfile')->nullable(true)->default('')->change();
$table->string('designer')->nullable(true)->default('')->change();
$table->string('comment')->nullable(true)->default('')->change();
});
}
/**

View File

@@ -1,5 +1,6 @@
<?php
use App\Models\SearchBox;
use Illuminate\Support\Str;
function get_langfolder_cookie($transToLocale = false)
@@ -2298,6 +2299,7 @@ function menu ($selected = "home") {
if ($menu) {
print $menu;
} else {
$lang = get_langfolder_cookie();
$normalSectionName = get_searchbox_value(get_setting('main.browsecat'), 'section_name');
$specialSectionName = get_searchbox_value(get_setting('main.specialcat'), 'section_name');
print ("<ul id=\"mainmenu\" class=\"menu\">");
@@ -2306,9 +2308,9 @@ function menu ($selected = "home") {
print ("<li" . ($selected == "forums" ? " class=\"selected\"" : "") . "><a href=\"forums.php\">".$lang_functions['text_forums']."</a></li>");
else
print ("<li" . ($selected == "forums" ? " class=\"selected\"" : "") . "><a href=\"" . $extforumurl."\" target=\"_blank\">".$lang_functions['text_forums']."</a></li>");
print ("<li" . ($selected == "torrents" ? " class=\"selected\"" : "") . "><a href=\"torrents.php\" rel='sub-menu'>".($normalSectionName ?: $lang_functions['text_torrents'])."</a></li>");
print ("<li" . ($selected == "torrents" ? " class=\"selected\"" : "") . "><a href=\"torrents.php\" rel='sub-menu'>".($normalSectionName[$lang] ?? $lang_functions['text_torrents'])."</a></li>");
if ($enablespecial == 'yes' && user_can('view_special_torrent'))
print ("<li" . ($selected == "special" ? " class=\"selected\"" : "") . "><a href=\"special.php\">".($specialSectionName ?: $lang_functions['text_special'])."</a></li>");
print ("<li" . ($selected == "special" ? " class=\"selected\"" : "") . "><a href=\"special.php\">".($specialSectionName[$lang] ?? $lang_functions['text_special'])."</a></li>");
if ($enableoffer == 'yes')
print ("<li" . ($selected == "offers" ? " class=\"selected\"" : "") . "><a href=\"offers.php\">".$lang_functions['text_offers']."</a></li>");
if ($enablerequest == 'yes')
@@ -2904,7 +2906,7 @@ function stdfoot() {
$yearfounded = ($year ? $year : 2007);
print(" (c) "." <a href=\"" . get_protocol_prefix() . $BASEURL."\" target=\"_self\">".$SITENAME."</a> ".($icplicense_main ? " ".$icplicense_main." " : "").(date("Y") != $yearfounded ? $yearfounded."-" : "").date("Y")." ".VERSION."<br /><br />");
printf ("[page created in <b> %s </b> sec", sprintf("%.3f", $totaltime));
print (" with <b>".count($query_name)."</b> db queries, <b>".$Cache->getCacheReadTimes()."</b> reads and <b>".$Cache->getCacheWriteTimes()."</b> writes of Redis and <b>".mksize(memory_get_usage())."</b> ram]");
print (", takes up <b>".mksize(memory_get_usage())."</b> ram]");
print ("</div>\n");
if ($enablesqldebug_tweak == 'yes' && get_user_class() >= $sqldebug_tweak) {
print("<div id=\"sql_debug\" style='text-align: left;'>SQL query list: <ul>");
@@ -3263,10 +3265,10 @@ function searchbox_item_list($table, $mode){
$cacheKey = "{$table}_list_mode_{$mode}";
if (!$ret = $Cache->get_value($cacheKey)){
$ret = array();
$res = sql_query("SELECT * FROM $table where mode = '$mode' ORDER BY sort_index, id");
$res = sql_query("SELECT * FROM $table where (mode = '$mode' or mode = 0) ORDER BY sort_index, id");
while ($row = mysql_fetch_array($res))
$ret[] = $row;
$Cache->cache_value($cacheKey, $ret, 152800);
$Cache->cache_value($cacheKey, $ret, 3600);
}
return $ret;
}
@@ -4341,9 +4343,10 @@ function get_second_icon($row) //for CHDBits
$processing=$row['processing'];
$team=$row['team'];
$audiocodec=$row['audiocodec'];
$mode = $row['search_box_id'];
$cacheKey = 'secondicon_'.$source.'_'.$medium.'_'.$codec.'_'.$standard.'_'.$processing.'_'.$team.'_'.$audiocodec.'_content';
if (!$sirow = $Cache->get_value($cacheKey)){
$res = sql_query("SELECT * FROM secondicons WHERE (source = ".sqlesc($source)." OR source=0) AND (medium = ".sqlesc($medium)." OR medium=0) AND (codec = ".sqlesc($codec)." OR codec = 0) AND (standard = ".sqlesc($standard)." OR standard = 0) AND (processing = ".sqlesc($processing)." OR processing = 0) AND (team = ".sqlesc($team)." OR team = 0) AND (audiocodec = ".sqlesc($audiocodec)." OR audiocodec = 0) LIMIT 1");
$res = sql_query("SELECT * FROM secondicons WHERE (mode = ".sqlesc($mode)." OR mode = 0) AND (source = ".sqlesc($source)." OR source=0) AND (medium = ".sqlesc($medium)." OR medium=0) AND (codec = ".sqlesc($codec)." OR codec = 0) AND (standard = ".sqlesc($standard)." OR standard = 0) AND (processing = ".sqlesc($processing)." OR processing = 0) AND (team = ".sqlesc($team)." OR team = 0) AND (audiocodec = ".sqlesc($audiocodec)." OR audiocodec = 0) LIMIT 1");
$sirow = mysql_fetch_array($res);
if (!$sirow)
$sirow = 'not allowed';
@@ -4843,6 +4846,9 @@ function get_searchbox_value($mode = 1, $item = 'showsubcat'){
while ($row = mysql_fetch_array($res)) {
if (isset($row['extra'])) {
$row['extra'] = json_decode($row['extra'], true);
}
if (isset($row['section_name'])) {
$row['section_name'] = json_decode($row['section_name'], true);
}
$rows[$row['id']] = $row;
}
@@ -5988,20 +5994,34 @@ function calculate_harem_addition($uid)
}
function build_search_box_category_table($mode, $checkboxValue, $categoryHrefPrefix, $taxonomyHrefPrefix, $taxonomyNameLength, $checkedValues = '')
function build_search_box_category_table($mode, $checkboxValue, $categoryHrefPrefix, $taxonomyHrefPrefix, $taxonomyNameLength, $checkedValues = '', array $options = [])
{
$searchBox = \App\Models\SearchBox::query()->with(['categories', 'categories.icon'])->findOrFail($mode);
$lang = get_langfolder_cookie();
$withTaxonomies = [];
foreach (\App\Models\SearchBox::$taxonomies as $torrentField => $taxonomyTable) {
$showField = "show" . $torrentField;
if ($searchBox->{$showField}) {
$withTaxonomies[] = "taxonomy_{$torrentField}";
if ($searchBox->showsubcat) {
//Keep the order
if (!empty($searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS])) {
foreach ($searchBox->extra[SearchBox::EXTRA_TAXONOMY_LABELS] as $taxonomyLabelInfo) {
$torrentField = $taxonomyLabelInfo["torrent_field"];
$showField = "show" . $torrentField;
if ($searchBox->{$showField}) {
$withTaxonomies[$torrentField] = \App\Models\SearchBox::$taxonomies[$torrentField];
}
}
} else {
foreach (\App\Models\SearchBox::$taxonomies as $torrentField => $taxonomyTable) {
$showField = "show" . $torrentField;
if ($searchBox->{$showField}) {
$withTaxonomies[$torrentField] = $taxonomyTable;
}
}
}
}
$searchBox->load($withTaxonomies);
$html = '<table>';
$html .= sprintf('<caption><font class="big">%s</font></caption>', $searchBox->section_name);
if (!empty($options['section_name'])) {
$html .= sprintf('<caption><font class="big">%s</font></caption>', $searchBox->section_name[$lang] ?? '');
}
//Category
$html .= sprintf('<tr><td class="embedded" align="left">%s</td></tr>', nexus_trans('label.search_box.category'));
$categoryChunks = $searchBox->categories->chunk($searchBox->catsperrow);
@@ -6010,7 +6030,7 @@ function build_search_box_category_table($mode, $checkboxValue, $categoryHrefPre
$html .= '<tr>';
foreach ($chunk as $item) {
$checked = '';
if (str_contains($checkedValues, "[cat{$item->id}]")) {
if (str_contains($checkedValues, "[cat{$item->id}]") || str_contains($checkedValues, "cat{$item->id}=1")) {
$checked = " checked";
}
$icon = $item->icon;
@@ -6018,7 +6038,7 @@ function build_search_box_category_table($mode, $checkboxValue, $categoryHrefPre
$td = <<<TD
<td align="left" class="bottom" style="padding-bottom: 4px;padding-left: {$searchBox->catpadding}px">
<input type="checkbox" id="cat{$item->id}" name="cat{$item->id}" value="{$checkboxValue}"{$checked} />
<a href="{$categoryHrefPrefix}&cat={$item->id}"><img src="pic/cattrans.gif" class="{$item->class_name}" alt="{$item->name}" title="{$item->name}" style="background-image: url({$backgroundImagePath})" /></a>
<a href="{$categoryHrefPrefix}cat={$item->id}"><img src="pic/cattrans.gif" class="{$item->class_name}" alt="{$item->name}" title="{$item->name}" style="background-image: url({$backgroundImagePath})" /></a>
</td>
TD;
$html .= $td;
@@ -6026,29 +6046,33 @@ TD;
$html .= '</tr>';
}
//Taxonomy
foreach ($withTaxonomies as $relation) {
$torrentField = str_replace("taxonomy_", '', $relation);
foreach ($withTaxonomies as $torrentField => $tableName) {
if ($taxonomyNameLength > 0) {
$namePrefix = substr($torrentField, 0, $taxonomyNameLength);
} else {
$namePrefix = $torrentField;
}
$html .= sprintf('<tr><td class="embedded" align="left">%s</td></tr>', $searchBox->getTaxonomyLabel($torrentField));
$taxonomyChunks = $searchBox->{$relation}->chunk($searchBox->catsperrow);
$taxonomyChunks = \Nexus\Database\NexusDB::table($tableName)
->where(function (\Illuminate\Database\Query\Builder $query) use ($mode) {
return $query->where('mode', $mode)->orWhere('mode', 0);
})
->get()
->chunk($searchBox->catsperrow);
foreach ($taxonomyChunks as $chunk) {
$html .= '<tr>';
foreach ($chunk as $item) {
if ($taxonomyHrefPrefix) {
$afterInput = sprintf('<a href="%s&%s=%s">%s</a>', $taxonomyHrefPrefix, $namePrefix, $item->id, $item->name);
$afterInput = sprintf('<a href="%s%s=%s">%s</a>', $taxonomyHrefPrefix, $namePrefix, $item->id, $item->name);
} else {
$afterInput = $item->name;
}
$checked = '';
if (str_contains($checkedValues, "[{$namePrefix}{$item->id}]")) {
if (str_contains($checkedValues, "[{$namePrefix}{$item->id}]") || str_contains($checkedValues, "{$namePrefix}{$item->id}=1")) {
$checked = ' checked';
}
$td = <<<TD
<td align="left" class="bottom" style="padding-bottom: 4px;padding-left: {$item->catpadding}px">
<td align="left" class="bottom" style="padding-bottom: 4px;padding-left: {$searchBox->catpadding}px">
<label><input type="checkbox" id="{$namePrefix}{$item->id}" name="{$namePrefix}{$item->id}" value="{$checkboxValue}"{$checked} />$afterInput</label>
</td>
TD;

View File

@@ -10,8 +10,9 @@ int_check($id);
if (!isset($id) || !$id)
die();
$taxonomyFields = "sources.name AS source_name, media.name AS medium_name, codecs.name AS codec_name, standards.name AS standard_name, processings.name AS processing_name, teams.name AS team_name, audiocodecs.name AS audiocodec_name";
$res = sql_query("SELECT torrents.cache_stamp, torrents.sp_state, torrents.url, torrents.small_descr, torrents.seeders, torrents.banned, torrents.leechers, torrents.info_hash, torrents.filename, nfo, LENGTH(torrents.nfo) AS nfosz, torrents.last_action, torrents.name, torrents.owner, torrents.save_as, torrents.descr, torrents.visible, torrents.size, torrents.added, torrents.views, torrents.hits, torrents.times_completed, torrents.id, torrents.type, torrents.numfiles, torrents.anonymous, torrents.pt_gen, torrents.technical_info, torrents.hr, torrents.promotion_until, torrents.promotion_time_type, torrents.approval_status,
categories.name AS cat_name, categories.mode as search_box_id, sources.name AS source_name, media.name AS medium_name, codecs.name AS codec_name, standards.name AS standard_name, processings.name AS processing_name, teams.name AS team_name, audiocodecs.name AS audiocodec_name
categories.name AS cat_name, categories.mode as search_box_id, $taxonomyFields
FROM torrents LEFT JOIN categories ON torrents.category = categories.id
LEFT JOIN sources ON torrents.source = sources.id
LEFT JOIN media ON torrents.medium = media.id
@@ -42,6 +43,7 @@ if (!$row) {
$owner = \App\Models\User::defaultUser();
}
$torrentRep = new \App\Repositories\TorrentRepository();
$searchBoxRep = new \App\Repositories\SearchBoxRepository();
$torrentUpdate = [];
if (!empty($_GET["hit"])) {
$torrentUpdate[] = 'views = views + 1';
@@ -135,24 +137,30 @@ if (!$row) {
$size_info = "<b>".$lang_details['text_size']."</b>" . mksize($row["size"]);
$type_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['row_type'].":</b>&nbsp;".$row["cat_name"];
$source_info = $medium_info = $codec_info = $audiocodec_info = $standard_info = $processing_info = $team_info = '';
if (isset($row["source_name"]))
$source_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_source']."&nbsp;</b>".$row['source_name'];
if (isset($row["medium_name"]))
$medium_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_medium']."&nbsp;</b>".$row['medium_name'];
if (isset($row["codec_name"]))
$codec_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_codec']."&nbsp;</b>".$row['codec_name'];
if (isset($row["standard_name"]))
$standard_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_stardard']."&nbsp;</b>".$row['standard_name'];
if (isset($row["processing_name"]))
$processing_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_processing']."&nbsp;</b>".$row['processing_name'];
if (isset($row["team_name"]))
$team_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_team']."&nbsp;</b>".$row['team_name'];
if (isset($row["audiocodec_name"]))
$audiocodec_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_audio_codec']."&nbsp;</b>".$row['audiocodec_name'];
// $source_info = $medium_info = $codec_info = $audiocodec_info = $standard_info = $processing_info = $team_info = '';
// if (isset($row["source_name"]))
// $source_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_source']."&nbsp;</b>".$row['source_name'];
// if (isset($row["medium_name"]))
// $medium_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_medium']."&nbsp;</b>".$row['medium_name'];
// if (isset($row["codec_name"]))
// $codec_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_codec']."&nbsp;</b>".$row['codec_name'];
// if (isset($row["standard_name"]))
// $standard_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_stardard']."&nbsp;</b>".$row['standard_name'];
// if (isset($row["processing_name"]))
// $processing_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_processing']."&nbsp;</b>".$row['processing_name'];
// if (isset($row["team_name"]))
// $team_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_team']."&nbsp;</b>".$row['team_name'];
// if (isset($row["audiocodec_name"]))
// $audiocodec_info = "&nbsp;&nbsp;&nbsp;<b>".$lang_details['text_audio_codec']."&nbsp;</b>".$row['audiocodec_name'];
tr($lang_details['row_basic_info'], $size_info.$type_info.$source_info . $medium_info. $codec_info . $audiocodec_info. $standard_info . $processing_info . $team_info, 1);
// tr($lang_details['row_basic_info'], $size_info.$type_info.$source_info . $medium_info. $codec_info . $audiocodec_info. $standard_info . $processing_info . $team_info, 1);
$taxonomyInfo = $searchBoxRep->listTaxonomyInfo($row['search_box_id'], $row);
$taxonomyRendered = '';
foreach ($taxonomyInfo as $item) {
$taxonomyRendered .= sprintf('&nbsp;&nbsp;&nbsp;<b>%s: </b>%s', $item['label'], $item['value']);
}
tr($lang_details['row_basic_info'], $size_info.$type_info.$taxonomyRendered, 1);
$actions = [];
if ($CURUSER["downloadpos"] != "no") {
$actions[] = "<a title=\"".$lang_details['title_download_torrent']."\" href=\"download.php?id=".$id."\"><img class=\"dt_download\" src=\"pic/trans.gif\" alt=\"download\" />&nbsp;<b><font class=\"small\">".$lang_details['text_download_torrent']."</font></b></a>";
@@ -386,7 +394,16 @@ JS;
{
// $where_area = " url = " . sqlesc((int)$imdb_id) ." AND torrents.id != ".sqlesc($id);
$where_area = sprintf('torrents.id in (%s)', implode(',', $otherCopiesIdArr));
$copies_res = sql_query("SELECT torrents.id, torrents.name, torrents.sp_state, torrents.size, torrents.added, torrents.seeders, torrents.leechers, torrents.hr,categories.id AS catid, categories.name AS catname, categories.image AS catimage, sources.name AS source_name, media.name AS medium_name, codecs.name AS codec_name, standards.name AS standard_name, processings.name AS processing_name, categories.mode as search_box_id FROM torrents LEFT JOIN categories ON torrents.category=categories.id LEFT JOIN sources ON torrents.source = sources.id LEFT JOIN media ON torrents.medium = media.id LEFT JOIN codecs ON torrents.codec = codecs.id LEFT JOIN standards ON torrents.standard = standards.id LEFT JOIN processings ON torrents.processing = processings.id WHERE " . $where_area . " ORDER BY torrents.id DESC") or sqlerr(__FILE__, __LINE__);
$copies_res = sql_query("SELECT torrents.id, torrents.name, torrents.sp_state, torrents.size, torrents.added, torrents.seeders, torrents.leechers, torrents.hr,categories.id AS catid, categories.name AS catname, categories.image AS catimage, $taxonomyFields, categories.mode as search_box_id FROM torrents
LEFT JOIN categories ON torrents.category=categories.id
LEFT JOIN sources ON torrents.source = sources.id
LEFT JOIN media ON torrents.medium = media.id
LEFT JOIN codecs ON torrents.codec = codecs.id
LEFT JOIN standards ON torrents.standard = standards.id
LEFT JOIN teams ON torrents.team = teams.id
LEFT JOIN audiocodecs ON torrents.audiocodec = audiocodecs.id
LEFT JOIN processings ON torrents.processing = processings.id
WHERE " . $where_area . " ORDER BY torrents.id DESC") or sqlerr(__FILE__, __LINE__);
$copies_count = mysql_num_rows($copies_res);
if($copies_count > 0)
@@ -402,24 +419,26 @@ JS;
{
$dispname=substr($dispname, 0, $max_lenght_of_torrent_name) . "..";
}
$other_source_info = $other_medium_info = $other_codec_info = $other_standard_info = $other_processing_info = '';
if (isset($copy_row["source_name"]))
$other_source_info = $copy_row['source_name'].", ";
if (isset($copy_row["medium_name"]))
$other_medium_info = $copy_row['medium_name'].", ";
if (isset($copy_row["codec_name"]))
$other_codec_info = $copy_row['codec_name'].", ";
if (isset($copy_row["standard_name"]))
$other_standard_info = $copy_row['standard_name'].", ";
if (isset($copy_row["processing_name"]))
$other_processing_info = $copy_row['processing_name'].", ";
// $other_source_info = $other_medium_info = $other_codec_info = $other_standard_info = $other_processing_info = '';
// if (isset($copy_row["source_name"]))
// $other_source_info = $copy_row['source_name'].", ";
// if (isset($copy_row["medium_name"]))
// $other_medium_info = $copy_row['medium_name'].", ";
// if (isset($copy_row["codec_name"]))
// $other_codec_info = $copy_row['codec_name'].", ";
// if (isset($copy_row["standard_name"]))
// $other_standard_info = $copy_row['standard_name'].", ";
// if (isset($copy_row["processing_name"]))
// $other_processing_info = $copy_row['processing_name'].", ";
$taxonomyInfo = $searchBoxRep->listTaxonomyInfo($copy_row['search_box_id'], $copy_row);
$taxonomyValues = array_column($taxonomyInfo, 'value');
$sphighlight = get_torrent_bg_color($copy_row['sp_state']);
$sp_info = get_torrent_promotion_append($copy_row['sp_state'], '', false, '', 0, '', $copy_row['__ignore_global_sp_state'] ?? false);
$hrImg = get_hr_img($copy_row, $copy_row['search_box_id']);
$s .= "<tr". $sphighlight."><td class=\"rowfollow nowrap\" valign=\"middle\" style='padding: 0px'>".return_category_image($copy_row["catid"], "torrents.php?allsec=1&amp;")."</td><td class=\"rowfollow\" align=\"left\"><a href=\"" . htmlspecialchars(get_protocol_prefix() . $BASEURL . "/details.php?id=" . $copy_row["id"]. "&hit=1")."\">" . $dispname ."</a>". $sp_info. $hrImg ."</td>" .
"<td class=\"rowfollow\" align=\"left\">" . rtrim(trim($other_source_info . $other_medium_info . $other_codec_info . $other_standard_info . $other_processing_info), ","). "</td>" .
"<td class=\"rowfollow\" align=\"left\">" .implode(', ', $taxonomyValues). "</td>" .
"<td class=\"rowfollow\" align=\"center\">" . mksize($copy_row["size"]) . "</td>" .
"<td class=\"rowfollow nowrap\" align=\"center\">" . str_replace("&nbsp;", "<br />", gettime($copy_row["added"],false)). "</td>" .
"<td class=\"rowfollow\" align=\"center\">" . $copy_row["seeders"] . "</td>" .

View File

@@ -9,7 +9,7 @@ if (!$id)
die();
$res = sql_query("SELECT torrents.*, categories.mode as cat_mode FROM torrents LEFT JOIN categories ON category = categories.id WHERE torrents.id = $id");
$row = mysql_fetch_array($res);
$row = mysql_fetch_assoc($res);
if (!$row) die();
/**
@@ -150,14 +150,14 @@ else {
}
*/
$sectionCurrent = $searchBoxRep->renderQualitySelect($sectionmode);
tr($lang_edit['row_quality'], $sectionCurrent, 1, "hide mode mode_$sectionmode");
$sectionCurrent = $searchBoxRep->renderTaxonomySelect($sectionmode, $row);
tr($lang_edit['row_quality'], $sectionCurrent, 1, "mode_$sectionmode");
echo $customField->renderOnUploadPage($id, $sectionmode);
echo $hitAndRunRep->renderOnUploadPage($row['hr'], $sectionmode);
if ($allowmove && $othermode) {
$selectOther = $searchBoxRep->renderQualitySelect($othermode);
tr($lang_edit['row_quality'], $selectOther, 1, "hide mode mode_$othermode");
$selectOther = $searchBoxRep->renderTaxonomySelect($othermode, $row);
tr($lang_edit['row_quality'], $selectOther, 1, "mode_$othermode");
echo $customField->renderOnUploadPage($id, $othermode);
echo $hitAndRunRep->renderOnUploadPage($row['hr'], $othermode);
}

View File

@@ -300,10 +300,10 @@ if ($allowspecial) //print category list of Special section
$categories .= "</table>";
*/
$categories = build_search_box_category_table($browsecatmode, 'yes', 'torrents.php?allsec=1', false, 3);
$categories = build_search_box_category_table($browsecatmode, 'yes', 'torrents.php?allsec=1&', false, 3, '', ['section_name' => true]);
print($categories);
print '<div style="height: 1px;background-color: #eee;margin: 10px 0"></div>';
$categoriesSpecial = build_search_box_category_table($specialcatmode, 'yes', 'torrents.php?allsec=1', false, 3);
$categoriesSpecial = build_search_box_category_table($specialcatmode, 'yes', 'torrents.php?allsec=1&', false, 3, '', ['section_name' => true]);
print($categoriesSpecial);
?>
</td>

View File

@@ -92,13 +92,13 @@ $updateset[] = "url = " . sqlesc($url);
$updateset[] = "small_descr = " . sqlesc($_POST["small_descr"]);
//$updateset[] = "ori_descr = " . sqlesc($descr);
$updateset[] = "category = " . sqlesc($catid);
$updateset[] = "source = " . sqlesc(intval($_POST["source_sel"] ?? 0));
$updateset[] = "medium = " . sqlesc(intval($_POST["medium_sel"] ?? 0));
$updateset[] = "codec = " . sqlesc(intval($_POST["codec_sel"] ?? 0));
$updateset[] = "standard = " . sqlesc(intval($_POST["standard_sel"] ?? 0));
$updateset[] = "processing = " . sqlesc(intval($_POST["processing_sel"] ?? 0));
$updateset[] = "team = " . sqlesc(intval($_POST["team_sel"] ?? 0));
$updateset[] = "audiocodec = " . sqlesc(intval($_POST["audiocodec_sel"] ?? 0));
$updateset[] = "source = " . sqlesc(intval($_POST["source_sel"][$newcatmode] ?? 0));
$updateset[] = "medium = " . sqlesc(intval($_POST["medium_sel"][$newcatmode] ?? 0));
$updateset[] = "codec = " . sqlesc(intval($_POST["codec_sel"][$newcatmode] ?? 0));
$updateset[] = "standard = " . sqlesc(intval($_POST["standard_sel"][$newcatmode] ?? 0));
$updateset[] = "processing = " . sqlesc(intval($_POST["processing_sel"][$newcatmode] ?? 0));
$updateset[] = "team = " . sqlesc(intval($_POST["team_sel"][$newcatmode] ?? 0));
$updateset[] = "audiocodec = " . sqlesc(intval($_POST["audiocodec_sel"][$newcatmode] ?? 0));
if (user_can('torrentmanage')) {
$updateset[] = "visible = '" . (isset($_POST["visible"]) && $_POST["visible"] ? "yes" : "no") . "'";
}

View File

@@ -68,13 +68,17 @@ if (!$descr)
bark($lang_takeupload['std_blank_description']);
$catid = intval($_POST["type"] ?? 0);
$sourceid = intval($_POST["source_sel"] ?? 0);
$mediumid = intval($_POST["medium_sel"] ?? 0);
$codecid = intval($_POST["codec_sel"] ?? 0);
$standardid = intval($_POST["standard_sel"] ?? 0);
$processingid = intval($_POST["processing_sel"] ?? 0);
$teamid = intval($_POST["team_sel"] ?? 0);
$audiocodecid = intval($_POST["audiocodec_sel"] ?? 0);
$catmod = get_single_value("categories","mode","WHERE id=".sqlesc($catid));
if (!$catmod) {
bark('Invalid category');
}
$sourceid = intval($_POST["source_sel"][$catmod] ?? 0);
$mediumid = intval($_POST["medium_sel"][$catmod] ?? 0);
$codecid = intval($_POST["codec_sel"][$catmod] ?? 0);
$standardid = intval($_POST["standard_sel"][$catmod] ?? 0);
$processingid = intval($_POST["processing_sel"][$catmod] ?? 0);
$teamid = intval($_POST["team_sel"][$catmod] ?? 0);
$audiocodecid = intval($_POST["audiocodec_sel"][$catmod] ?? 0);
if (!is_valid_id($catid))
bark($lang_takeupload['std_category_unselected']);
@@ -177,7 +181,6 @@ if (\App\Models\Torrent::query()->where('info_hash', $infohash)->exists()) {
$allowtorrents = user_can_upload("torrents");
$allowspecial = user_can_upload("music");
$catmod = get_single_value("categories","mode","WHERE id=".sqlesc($catid));
$offerid = intval($_POST['offer'] ?? 0);
$is_offer=false;
if ($browsecatmode != $specialcatmode && $catmod == $specialcatmode){//upload to special section

View File

@@ -102,15 +102,13 @@ if (isset($_GET['sort']) && $_GET['sort'] && isset($_GET['type']) && $_GET['type
$addparam = "";
$wherea = array();
$wherecatina = array();
if ($showsubcat){
if ($showsource) $wheresourceina = array();
if ($showmedium) $wheremediumina = array();
if ($showcodec) $wherecodecina = array();
if ($showstandard) $wherestandardina = array();
if ($showprocessing) $whereprocessingina = array();
if ($showteam) $whereteamina = array();
if ($showaudiocodec) $whereaudiocodecina = array();
}
$wheresourceina = array();
$wheremediumina = array();
$wherecodecina = array();
$wherestandardina = array();
$whereprocessingina = array();
$whereteamina = array();
$whereaudiocodecina = array();
//----------------- start whether show torrents from all sections---------------------//
if ($_GET)
$allsec = intval($_GET["allsec"] ?? 0);
@@ -946,45 +944,46 @@ if ($allsec != 1 || $enablespecial != 'yes'){ //do not print searchbox if showin
<tbody id="ksearchboxmain" style="display:none">
<tr>
<td class="rowfollow" align="left">
<table>
<?php
function printcat($name, $listarray, $cbname, $wherelistina, $btname, $showimg = false)
{
global $catpadding,$catsperrow,$lang_torrents,$CURUSER,$CURLANGDIR,$catimgurl;
print("<tr><td class=\"embedded\" colspan=\"".$catsperrow."\" align=\"left\"><b>".$name."</b></td></tr><tr>");
$i = 0;
foreach($listarray as $list){
if ($i && $i % $catsperrow == 0){
print("</tr><tr>");
}
print("<td align=\"left\" class=\"bottom\" style=\"padding-bottom: 4px; padding-left: ".$catpadding."px;\"><input type=\"checkbox\" id=\"".$cbname.$list['id']."\" name=\"".$cbname.$list['id']."\"" . (in_array($list['id'],$wherelistina) ? " checked=\"checked\"" : "") . " value=\"1\" />".($showimg ? return_category_image($list['id'], "?") : "<a title=\"" .$list['name'] . "\" href=\"?".$cbname."=".$list['id']."\">".$list['name']."</a>")."</td>\n");
$i++;
}
$checker = "<input name=\"".$btname."\" value='" . $lang_torrents['input_check_all'] . "' class=\"btn medium\" type=\"button\" onclick=\"javascript:SetChecked('".$cbname."','".$btname."','". $lang_torrents['input_check_all'] ."','" . $lang_torrents['input_uncheck_all'] . "',-1,10)\" />";
print("<td colspan=\"2\" class=\"bottom\" align=\"left\" style=\"padding-left: 15px\">".$checker."</td>\n");
print("</tr>");
}
printcat($lang_torrents['text_category'],$cats,"cat",$wherecatina,"cat_check",true);
if ($showsubcat){
if ($showsource)
printcat($lang_torrents['text_source'], $sources, "source", $wheresourceina, "source_check");
if ($showmedium)
printcat($lang_torrents['text_medium'], $media, "medium", $wheremediumina, "medium_check");
if ($showcodec)
printcat($lang_torrents['text_codec'], $codecs, "codec", $wherecodecina, "codec_check");
if ($showaudiocodec)
printcat($lang_torrents['text_audio_codec'], $audiocodecs, "audiocodec", $whereaudiocodecina, "audiocodec_check");
if ($showstandard)
printcat($lang_torrents['text_standard'], $standards, "standard", $wherestandardina, "standard_check");
if ($showprocessing)
printcat($lang_torrents['text_processing'], $processings, "processing", $whereprocessingina, "processing_check");
if ($showteam)
printcat($lang_torrents['text_team'], $teams, "team", $whereteamina, "team_check");
}
?>
</table>
<!-- <table>-->
<!-- --><?php
// function printcat($name, $listarray, $cbname, $wherelistina, $btname, $showimg = false)
// {
// global $catpadding,$catsperrow,$lang_torrents,$CURUSER,$CURLANGDIR,$catimgurl;
//
// print("<tr><td class=\"embedded\" colspan=\"".$catsperrow."\" align=\"left\"><b>".$name."</b></td></tr><tr>");
// $i = 0;
// foreach($listarray as $list){
// if ($i && $i % $catsperrow == 0){
// print("</tr><tr>");
// }
// print("<td align=\"left\" class=\"bottom\" style=\"padding-bottom: 4px; padding-left: ".$catpadding."px;\"><input type=\"checkbox\" id=\"".$cbname.$list['id']."\" name=\"".$cbname.$list['id']."\"" . (in_array($list['id'],$wherelistina) ? " checked=\"checked\"" : "") . " value=\"1\" />".($showimg ? return_category_image($list['id'], "?") : "<a title=\"" .$list['name'] . "\" href=\"?".$cbname."=".$list['id']."\">".$list['name']."</a>")."</td>\n");
// $i++;
// }
// $checker = "<input name=\"".$btname."\" value='" . $lang_torrents['input_check_all'] . "' class=\"btn medium\" type=\"button\" onclick=\"javascript:SetChecked('".$cbname."','".$btname."','". $lang_torrents['input_check_all'] ."','" . $lang_torrents['input_uncheck_all'] . "',-1,10)\" />";
// print("<td colspan=\"2\" class=\"bottom\" align=\"left\" style=\"padding-left: 15px\">".$checker."</td>\n");
// print("</tr>");
// }
// printcat($lang_torrents['text_category'],$cats,"cat",$wherecatina,"cat_check",true);
//
// if ($showsubcat){
// if ($showsource)
// printcat($lang_torrents['text_source'], $sources, "source", $wheresourceina, "source_check");
// if ($showmedium)
// printcat($lang_torrents['text_medium'], $media, "medium", $wheremediumina, "medium_check");
// if ($showcodec)
// printcat($lang_torrents['text_codec'], $codecs, "codec", $wherecodecina, "codec_check");
// if ($showaudiocodec)
// printcat($lang_torrents['text_audio_codec'], $audiocodecs, "audiocodec", $whereaudiocodecina, "audiocodec_check");
// if ($showstandard)
// printcat($lang_torrents['text_standard'], $standards, "standard", $wherestandardina, "standard_check");
// if ($showprocessing)
// printcat($lang_torrents['text_processing'], $processings, "processing", $whereprocessingina, "processing_check");
// if ($showteam)
// printcat($lang_torrents['text_team'], $teams, "team", $whereteamina, "team_check");
// }
// ?>
<!-- </table>-->
<?php echo build_search_box_category_table($sectiontype, '1', '?', '?', 0, $_SERVER['QUERY_STRING'])?>
</td>
<td class="rowfollow" valign="middle">

View File

@@ -154,14 +154,14 @@ stdhead($lang_upload['head_upload']);
$customField = new \Nexus\Field\Field();
$hitAndRunRep = new \App\Repositories\HitAndRunRepository();
if ($allowtorrents) {
$selectNormal = $searchBoxRep->renderQualitySelect($browsecatmode);
tr($lang_upload['row_quality'], $selectNormal, 1, "hide mode mode_$browsecatmode");
$selectNormal = $searchBoxRep->renderTaxonomySelect($browsecatmode);
tr($lang_upload['row_quality'], $selectNormal, 1, "mode_$browsecatmode");
echo $customField->renderOnUploadPage(0, $browsecatmode);
echo $hitAndRunRep->renderOnUploadPage('', $browsecatmode);
}
if ($allowspecial) {
$selectNormal = $searchBoxRep->renderQualitySelect($specialcatmode);
tr($lang_upload['row_quality'], $selectNormal, 1, "hide mode mode_$specialcatmode");
$selectNormal = $searchBoxRep->renderTaxonomySelect($specialcatmode);
tr($lang_upload['row_quality'], $selectNormal, 1, "mode_$specialcatmode");
echo $customField->renderOnUploadPage(0, $specialcatmode);
echo $hitAndRunRep->renderOnUploadPage('', $specialcatmode);
}

View File

@@ -540,9 +540,9 @@ if ($showaudiocodec) $audiocodecs = searchbox_item_list("audiocodecs");
$categories .= "<tr><td class=bottom><b>".$lang_usercp['text_show_dead_active']."</b><br /><select name=\"incldead\"><option value=\"0\" ".(strpos($CURUSER['notifs'], "[incldead=0]") !== false ? " selected" : "").">".$lang_usercp['select_including_dead']."</option><option value=\"1\" ".(strpos($CURUSER['notifs'], "[incldead=1]") !== false || strpos($CURUSER['notifs'], "incldead") == false ? " selected" : "").">".$lang_usercp['select_active']."</option><option value=\"2\" ".(strpos($CURUSER['notifs'], "[incldead=2]") !== false ? " selected" : "").">".$lang_usercp['select_dead']."</option></select></td><td class=bottom align=left><b>".$lang_usercp['text_show_special_torrents']."</b><br /><select name=\"spstate\"><option value=\"0\" ".($special_state == 0 ? " selected" : "").">".$lang_usercp['select_all']."</option>".promotion_selection($special_state)."</select></td><td class=bottom><b>".$lang_usercp['text_show_bookmarked']."</b><br /><select name=\"inclbookmarked\"><option value=\"0\" ".(strpos($CURUSER['notifs'], "[inclbookmarked=0]") !== false ? " selected" : "").">".$lang_usercp['select_all']."</option><option value=\"1\" ".(strpos($CURUSER['notifs'], "[inclbookmarked=1]") !== false ? " selected" : "")." >".$lang_usercp['select_bookmarked']."</option><option value=\"2\" ".(strpos($CURUSER['notifs'], "[inclbookmarked=2]") !== false ? " selected" : "").">".$lang_usercp['select_bookmarked_exclude']."</option></select></td></tr>";
$categories .= "</table>";
*/
$categories = build_search_box_category_table($browsecatmode, 'yes','torrents.php?allsec=1', false, 3, $CURUSER['notifs']);
$categories = build_search_box_category_table($browsecatmode, 'yes','torrents.php?allsec=1', false, 3, $CURUSER['notifs'], ['section_name' => true]);
$delimiter = '<div style="height: 1px;background-color: #eee;margin: 10px 0"></div>';
$categoriesSpecial = build_search_box_category_table($specialcatmode, 'yes','torrents.php?allsec=1', false, 3, $CURUSER['notifs']);
$categoriesSpecial = build_search_box_category_table($specialcatmode, 'yes','torrents.php?allsec=1', false, 3, $CURUSER['notifs'], ['section_name' => true]);
$extra = "<table><caption><font class='big'>{$lang_usercp['text_additional_selection']}</font></caption><tr><td class=bottom><b>".$lang_usercp['text_show_dead_active']."</b><br /><select name=\"incldead\"><option value=\"0\" ".(strpos($CURUSER['notifs'], "[incldead=0]") !== false ? " selected" : "").">".$lang_usercp['select_including_dead']."</option><option value=\"1\" ".(strpos($CURUSER['notifs'], "[incldead=1]") !== false || strpos($CURUSER['notifs'], "incldead") == false ? " selected" : "").">".$lang_usercp['select_active']."</option><option value=\"2\" ".(strpos($CURUSER['notifs'], "[incldead=2]") !== false ? " selected" : "").">".$lang_usercp['select_dead']."</option></select></td><td class=bottom align=left><b>".$lang_usercp['text_show_special_torrents']."</b><br /><select name=\"spstate\"><option value=\"0\" ".($special_state == 0 ? " selected" : "").">".$lang_usercp['select_all']."</option>".promotion_selection($special_state)."</select></td><td class=bottom><b>".$lang_usercp['text_show_bookmarked']."</b><br /><select name=\"inclbookmarked\"><option value=\"0\" ".(strpos($CURUSER['notifs'], "[inclbookmarked=0]") !== false ? " selected" : "").">".$lang_usercp['select_all']."</option><option value=\"1\" ".(strpos($CURUSER['notifs'], "[inclbookmarked=1]") !== false ? " selected" : "")." >".$lang_usercp['select_bookmarked']."</option><option value=\"2\" ".(strpos($CURUSER['notifs'], "[inclbookmarked=2]") !== false ? " selected" : "").">".$lang_usercp['select_bookmarked_exclude']."</option></select></td></tr></table>";
tr_small($lang_usercp['row_browse_default_categories'],$categories . $delimiter . $categoriesSpecial . $delimiter . $extra,1);
$ss_r = sql_query("SELECT * FROM stylesheets") or die;

View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

11
resources/js/app.js vendored
View File

@@ -1 +1,10 @@
require('./bootstrap');
import Alpine from 'alpinejs'
import AlpineFloatingUI from '@awcodes/alpine-floating-ui'
import NotificationsAlpinePlugin from '../../vendor/filament/notifications/dist/module.esm'
Alpine.plugin(AlpineFloatingUI)
Alpine.plugin(NotificationsAlpinePlugin)
window.Alpine = Alpine
Alpine.start()

View File

@@ -24,9 +24,11 @@ return [
'torrent_deny_reason' => '拒绝原因',
'roles' => '角色',
'permissions' => '权限',
'section' => '分',
'section' => '分类模式',
'icon' => '分类图标',
'plugin' => '插件',
'category' => '主分类',
'second_icon' => '第二图标',
],
'resources' => [
'agent_allow' => [

View File

@@ -243,7 +243,7 @@ return [
],
],
'search_box' => [
'label' => '分',
'label' => '分类模式',
'name' => '名称',
'section_name' => '分区名称',
'section_name_help' => '若设置,显示在菜单上',
@@ -271,6 +271,8 @@ return [
'image' => '图片文件名',
'image_help' => '图片文件的名字。允许的字符:[a-z](小写),[0-9][_./]。',
'icon_id' => '分类图标',
'mode' => '分区',
'mode_help' => '留空表示适用于全部分区',
],
],
'icon' => [
@@ -301,4 +303,15 @@ return [
第二图标='是'
你应该将一个电影类型的图标(如'movies.png')文件放入'pic/category/chd/nanosofts/',将一个第二图标(如'bdh264.png')放入'pic/category/chd/nanosofts/additional/'。",
],
'second_icon' => [
'label' => '第二图标',
'name' => '名字',
'name_help' => '不要使用过长的名字。建议在10个字母内。',
'image' => "图片文件名",
'image_help' => "图片文件的名字。允许的字符:[a-z](小写),[0-9][_./]。",
'class_name' => 'class属性值',
'class_name_help' => "为图片指定class属性值。若无请留空。允许的字符: [a-z](小写),[0-9][_],第一个字符必须是字母。",
'select_section' => '选择',
'select_section_help' => "如果某个选择未指定,其所有选项都符合此规则。必须至少指定一个选择。",
],
];

View File

@@ -8,7 +8,7 @@ return [
'sub_category_team_label' => '制作组',
'sub_category_processing_label' => '处理',
'sub_category_codec_label' => '编码',
'sub_category_audio_codec_label' => '音频编码',
'sub_category_audiocodec_label' => '音频编码',
'extras' => [
\App\Models\SearchBox::EXTRA_DISPLAY_COVER_ON_TORRENT_LIST => '种子列表页展示封面',
\App\Models\SearchBox::EXTRA_DISPLAY_SEED_BOX_ICON_ON_TORRENT_LIST => '种子列表页展示 SeedBox 图标',

View File

@@ -1,11 +1,12 @@
<x-filament::page
:widget-data="['record' => $record]"
:class="\Illuminate\Support\Arr::toCssClasses([
'filament-resources-create-record-page',
'filament-resources-edit-record-page',
'filament-resources-' . str_replace('/', '-', $this->getResource()::getSlug()),
'filament-resources-record-' . $record->getKey(),
])"
>
@capture($form)
<x-filament::form wire:submit.prevent="save">
<div style="margin-bottom: 40px;white-space: pre-wrap">{!! $desc !!}</div>
<hr/>
@@ -16,10 +17,33 @@
:full-width="$this->hasFullWidthFormActions()"
/>
</x-filament::form>
@endcapture
@if (count($relationManagers = $this->getRelationManagers()))
<x-filament::hr />
@php
$relationManagers = $this->getRelationManagers();
@endphp
<x-filament::resources.relation-managers :active-manager="$activeRelationManager" :managers="$relationManagers" :owner-record="$record" :page-class="static::class" />
@if ((! $this->hasCombinedRelationManagerTabsWithForm()) || (! count($relationManagers)))
{{ $form() }}
@endif
@if (count($relationManagers))
@if (! $this->hasCombinedRelationManagerTabsWithForm())
<x-filament::hr />
@endif
<x-filament::resources.relation-managers
:active-manager="$activeRelationManager"
:form-tab-label="$this->getFormTabLabel()"
:managers="$relationManagers"
:owner-record="$record"
:page-class="static::class"
>
@if ($this->hasCombinedRelationManagerTabsWithForm())
<x-slot name="form">
{{ $form() }}
</x-slot>
@endif
</x-filament::resources.relation-managers>
@endif
</x-filament::page>

18
tailwind.config.js vendored Normal file
View File

@@ -0,0 +1,18 @@
const colors = require('tailwindcss/colors')
module.exports = {
content: [
'./resources/**/*.blade.php',
'./vendor/filament/**/*.blade.php',
],
theme: {
extend: {
colors: {
danger: colors.rose,
primary: colors.blue,
success: colors.green,
warning: colors.yellow,
},
},
},
}

4
webpack.mix.js vendored
View File

@@ -12,6 +12,6 @@ const mix = require('laravel-mix');
*/
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
//
.postCss('resources/css/app.css', 'public/styles', [
require('tailwindcss'),
]);