This commit is contained in:
f4ilji
2024-10-14 14:56:10 +05:00
parent 77b3e3b4b1
commit dd3a0c6ecd
258 changed files with 6548 additions and 1777 deletions
@@ -46,7 +46,7 @@ class CustomFormForm
TextInput::make('title')->label('Заголовок')->required()
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string|null $state, Forms\Set $set) {
$set('form_id', Str::slug($state));
$set('form_id', Str::slug($state) . Carbon::now()->timestamp);
}),
TextInput::make('form_id')->label('ID формы')->unique(ignoreRecord: true)->required(),
]),
@@ -77,7 +77,8 @@ class CustomFormForm
]),
Builder\Block::make('answers')->schema([]),
])->required(),
])->collapsed(),
])
->collapsed(),
]),
]),
])
@@ -197,9 +197,51 @@ class FormBuilderItem
RuleRequiredComponent::getComponent(),
]),
]),
Builder\Block::make('additional_education_choice')
->label('Выбрать дополнительное образование')
->schema([
TextInput::make('title_field')
->label('Заголовок поля')
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string $state, Forms\Set $set) {
$set('name_field', Str::slug($state) . Carbon::now()->timestamp );
}),
Forms\Components\Hidden::make('name_field')->required(),
Forms\Components\Textarea::make('description')->label('Описание поля (опционально)'),
Section::make('Настройка')
->statePath('rules')
->schema([
// RuleRequiredComponent::getComponent(),
// RuleLengthLimitComponent::getComponent(),
]),
])
->maxItems(1),
Builder\Block::make('educational_program_choice')
->label('Выбрать Образовательную программу')
->schema([
TextInput::make('title_field')
->label('Заголовок поля')
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string $state, Forms\Set $set) {
$set('name_field', Str::slug($state) . Carbon::now()->timestamp );
}),
Forms\Components\Hidden::make('name_field')->required(),
Forms\Components\Textarea::make('description')->label('Описание поля (опционально)'),
Section::make('Настройка')
->statePath('rules')
->schema([
RuleRequiredComponent::getComponent(),
RuleLengthLimitComponent::getComponent(),
]),
])
->maxItems(1),
])
->label('')
->addActionLabel('Добавить поле')
->blockPickerColumns(3)
->blockPickerWidth('2xl')
->collapsed();
}
+52 -38
View File
@@ -35,7 +35,11 @@ class PostForm
private static function findSeoActive(array $data) : bool
{
$bool = false;
foreach ($data as $item) {
if ($item['type'] !== 'paragraph') {
continue;
}
if ($item['data']['seo_active'] === true) {
$bool = true;
break;
@@ -92,6 +96,7 @@ class PostForm
->schema([
Toggle::make('seo_active')->label('Использовать блок как seo')
->live(onBlur: true)
->required()
->disabled(function ($state, Forms\Get $get) {
$data = $get('../../');
return self::findSeoActive($data) && !$state;
@@ -112,15 +117,21 @@ class PostForm
])
->label(''),
])->live(onBlur: true),
Builder\Block::make('files')->label('Файлы')
Builder\Block::make('files')
->schema([
Forms\Components\Repeater::make('file')->schema([
Hidden::make('expansion')->required(),
Hidden::make('size')->required(),
TextInput::make('title')
->required()
->maxLength(255)
->autofocus(),
FileUpload::make('path')
->required()
->getUploadedFileNameForStorageUsing(
fn (TemporaryUploadedFile $file): string =>
str(Str::slug(pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME) . '-' . Carbon::now()->timestamp ) . '.' . $file->getClientOriginalExtension())
)
->acceptedFileTypes([
'application/pdf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
@@ -132,10 +143,14 @@ class PostForm
->disk('public')
->directory('files')
->downloadable()
->afterStateUpdated(function ($set, $state) {
$set('expansion', $state?->getClientOriginalExtension());
$set('size', ByteConverter::bytesToHuman($state?->getSize()));
})
->visibility('public')
]),
]),
Builder\Block::make('person')->label('Персона')
Builder\Block::make('person')
->schema([
TextInput::make('name')
->label('Имя')
@@ -158,7 +173,7 @@ class PostForm
]),
])->minItems(1),
]),
Builder\Block::make('stepper')->label('Этапы')
Builder\Block::make('stepper')
->schema([
TextInput::make('step_name')
->label('Название шага')
@@ -167,18 +182,11 @@ class PostForm
Forms\Components\Repeater::make('steps')->schema([
TextInput::make('title')
->required()
->live()
->maxLength(255)->columnSpanFull(),
RichEditor::make('content')->required(),
])
->itemLabel(fn (array $state): ?string => $state['title'] ?? null)
->minItems(1)
->collapsible()
->collapsed()
])->minItems(1),
]),
Builder\Block::make('tabs')->label('Вкладки')
Builder\Block::make('tabs')
->schema([
Forms\Components\Repeater::make('tab')->schema([
TextInput::make('title')
@@ -344,24 +352,7 @@ class PostForm
->addActionLabel('Добавить новый блок'),
])->minItems(1),
]),
Builder\Block::make('images')->label('Слайдер изображений')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
]),
Builder\Block::make('image')->label('Изображение')
Builder\Block::make('images')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
@@ -376,8 +367,24 @@ class PostForm
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
]),
Builder\Block::make('video')->label('Видео')
])->label('Слайдер изображений'),
Builder\Block::make('image')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
])->label('Изображение'),
Builder\Block::make('video')
->schema([
TextInput::make('mime')->readOnly(),
TextInput::make('title')
@@ -402,7 +409,7 @@ class PostForm
->directory('videos')
->afterStateUpdated(fn (callable $set, $state) => $set('mime', $state?->getMimeType())),
]),
Builder\Block::make('postsList')->label('Список новостей')
Builder\Block::make('postsList')
->schema([
Forms\Components\Grid::make(2)->schema([
TextInput::make('count')
@@ -411,21 +418,28 @@ class PostForm
Select::make('category')
->options(Category::all()->pluck('title', 'id'))
]),
]),
Builder\Block::make('postItem')->label('Новость')
])->label('Список новостей'),
Builder\Block::make('postItem')
->schema([
Select::make('post')
->options(Post::query()->where('status', PostStatus::PUBLISHED)->pluck('title', 'id'))
->searchable()
->required(),
]),
Builder\Block::make('pageItem')->label('Страница')
])->label('Новость'),
Builder\Block::make('pageItem')
->schema([
Select::make('page')
->options(Page::query()->where('title', '!=' , null)->where('is_visible', true)->pluck('title', 'id'))
->searchable()
->required(),
]),
])->label('Страница'),
Builder\Block::make('customForm')
->schema([
Select::make('form')
->options(CustomForm::query()->where('status', CustomFormStatus::PUBLISHED)->pluck('title', 'form_id'))
->searchable()
->required(),
])->label('Форма'),
])
->collapsed()
->blockNumbers(false)
@@ -7,12 +7,14 @@ use App\Filament\Resources\AdditionalEducationCategoryResource\RelationManagers;
use App\Models\AdditionalEducationCategory;
use App\Models\DirectionAdditionalEducation;
use Filament\Forms;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Str;
class AdditionalEducationCategoryResource extends Resource
{
@@ -31,7 +33,13 @@ class AdditionalEducationCategoryResource extends Resource
return $form
->schema([
Forms\Components\Grid::make('2')->schema([
Forms\Components\TextInput::make('title')->required(),
TextInput::make('title')->label('Заголовок')->required()
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string|null $state, Forms\Set $set) {
$set('slug', Str::slug($state));
$set('seo.title', $state);
}),
TextInput::make('slug')->label('Slug')->unique(ignoreRecord: true)->readOnly()->required(),
Forms\Components\Select::make('dir_addit_educat_id')->required()
->options(DirectionAdditionalEducation::where('is_active', true)->pluck('title', 'id'))
]),
@@ -2,14 +2,17 @@
namespace App\Filament\Resources;
use App\Enums\CustomFormStatus;
use App\Enums\FormEducation;
use App\Enums\LevelEducational;
use App\Enums\PostStatus;
use App\Filament\Resources\AdditionalEducationResource\Pages;
use App\Filament\Resources\AdditionalEducationResource\RelationManagers;
use App\Helpers\ByteConverter;
use App\Models\AdditionalEducation;
use App\Models\AdditionalEducationCategory;
use App\Models\Category;
use App\Models\CustomForm;
use App\Models\DirectionAdditionalEducation;
use App\Models\Page;
use App\Models\Post;
@@ -23,12 +26,15 @@ use Filament\Forms\Components\Select;
use Filament\Forms\Components\SpatieTagsInput;
use Filament\Forms\Components\Tabs;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Mohamedsabil83\FilamentFormsTinyeditor\Components\TinyEditor;
class AdditionalEducationResource extends Resource
@@ -46,155 +52,256 @@ class AdditionalEducationResource extends Resource
{
return $form
->schema([
Tabs::make('Tabs')
->tabs([
Tabs\Tab::make('Основная информация')
->schema([
Forms\Components\Grid::make('2')->schema([
Forms\Components\TextInput::make('title')->required(),
Forms\Components\Select::make('category_id')->required()
->options(AdditionalEducationCategory::where('is_active', true)->pluck('title', 'id'))
Section::make()->schema([
Tabs::make('Tabs')
->tabs([
Tabs\Tab::make('Основная информация')
->schema([
Forms\Components\Grid::make('2')->schema([
TextInput::make('title')->label('Заголовок')->required()
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string|null $state, Forms\Set $set) {
$set('slug', Str::slug($state));
}),
TextInput::make('slug')->label('Slug')->unique(ignoreRecord: true)->readOnly()->required(),
Forms\Components\Select::make('category_id')->required()
->options(AdditionalEducationCategory::where('is_active', true)->pluck('title', 'id'))
]),
Forms\Components\TextInput::make('target_group')->required()->columnSpanFull(),
Forms\Components\TextInput::make('qualification')->required()->columnSpanFull(),
Forms\Components\Grid::make('2')->schema([
Forms\Components\TextInput::make('price')->required()->integer(),
Forms\Components\TextInput::make('learning_time')->required()->integer(),
]),
Forms\Components\Select::make('form_education')->required()->options(FormEducation::class),
Forms\Components\Toggle::make('is_active')->columnSpanFull()->inline(false)->default(true),
]),
Forms\Components\TextInput::make('target_group')->required()->columnSpanFull(),
Forms\Components\TextInput::make('qualification')->required()->columnSpanFull(),
Forms\Components\Grid::make('2')->schema([
Forms\Components\TextInput::make('price')->required()->integer(),
Forms\Components\TextInput::make('learning_time')->required()->integer(),
]),
Forms\Components\Select::make('form_education')->required()->options(FormEducation::class),
Forms\Components\Toggle::make('is_active')->columnSpanFull()->inline(false)->default(true),
]),
Tabs\Tab::make('Контент')
->schema([
\Filament\Forms\Components\Builder::make('content')->label('')->blocks([
Builder\Block::make('heading')->label('Заголовок')
->schema([
TextInput::make('id')->hidden()->integer()->default(rand(2335235,324634264263426)),
TextInput::make('content')
->label('')
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string $state, Forms\Set $set, $get) {
}),
]),
Builder\Block::make('paragraph')->label('Текст')
->schema([
RichEditor::make('content')
->toolbarButtons([
'blockquote',
'bold',
'bulletList',
'italic',
'link',
'orderedList',
'redo',
'strike',
'underline',
'undo',
])
->label(''),
]),
Builder\Block::make('files')->label('Файлы')
->schema([
Forms\Components\Repeater::make('file')->schema([
TextInput::make('title')
->required()
->maxLength(255)
->autofocus(),
FileUpload::make('path')
->required()
->acceptedFileTypes([
'application/pdf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/zip'
])
->maxSize(512000)
->disk('public')
->directory('files')
->downloadable()
->visibility('public')
Tabs\Tab::make('Контент')
->schema([
Builder::make('content')->label('')->blocks([
Builder\Block::make('heading')->label('Заголовок')
->schema([
TextInput::make('id')->hidden()->integer()->default(rand(2335235,324634264263426)),
TextInput::make('content')
->label('')
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string $state, Forms\Set $set, $get) {
}),
]),
]),
Builder\Block::make('person')->label('Персона')
->schema([
TextInput::make('name')
->label('Имя')
->required()
->maxLength(255),
FileUpload::make('photo')
->label('Фотография')
->image()
->disk('public')
->directory('images')
->imageEditor(),
Forms\Components\Repeater::make('info')->schema([
Forms\Components\Grid::make(2)->schema([
TextInput::make('column')
Builder\Block::make('paragraph')
->schema([
RichEditor::make('content')
->toolbarButtons([
'blockquote',
'bold',
'bulletList',
'italic',
'link',
'orderedList',
'redo',
'strike',
'underline',
'undo',
])
->label(''),
])->label('Текст'),
Builder\Block::make('files')
->schema([
Forms\Components\Repeater::make('file')->schema([
Hidden::make('expansion')->required(),
Hidden::make('size')->required(),
TextInput::make('title')
->required()
->maxLength(255),
TextInput::make('content')
->maxLength(255)
->autofocus(),
FileUpload::make('path')
->required()
->maxLength(255),
->getUploadedFileNameForStorageUsing(
fn (TemporaryUploadedFile $file): string =>
str(Str::slug(pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME) . '-' . Carbon::now()->timestamp ) . '.' . $file->getClientOriginalExtension())
)
->acceptedFileTypes([
'application/pdf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/zip'
])
->maxSize(512000)
->disk('public')
->directory('files')
->downloadable()
->afterStateUpdated(function ($set, $state) {
$set('expansion', $state?->getClientOriginalExtension());
$set('size', ByteConverter::bytesToHuman($state?->getSize()));
})
->visibility('public')
]),
])->minItems(1),
]),
Builder\Block::make('stepper')->label('Этапы')
->schema([
TextInput::make('step_name')
->label('Название шага')
->required()
->maxLength(255),
Forms\Components\Repeater::make('steps')->schema([
TextInput::make('title')
]),
Builder\Block::make('person')
->schema([
TextInput::make('name')
->label('Имя')
->required()
->live()
->maxLength(255)->columnSpanFull(),
RichEditor::make('content')->required(),
])
->itemLabel(fn (array $state): ?string => $state['title'] ?? null)
->minItems(1)
->collapsible()
->collapsed()
]),
Builder\Block::make('tabs')->label('Вкладки')
->schema([
Forms\Components\Repeater::make('tab')->schema([
TextInput::make('title')
->maxLength(255),
FileUpload::make('photo')
->label('Фотография')
->image()
->disk('public')
->directory('images')
->imageEditor(),
Forms\Components\Repeater::make('info')->schema([
Forms\Components\Grid::make(2)->schema([
TextInput::make('column')
->required()
->maxLength(255),
TextInput::make('content')
->required()
->maxLength(255),
]),
])->minItems(1),
]),
Builder\Block::make('stepper')
->schema([
TextInput::make('step_name')
->label('Название шага')
->required()
->maxLength(255)->columnSpanFull(),
\Filament\Forms\Components\Builder::make('content')->label('')->blocks([
Builder\Block::make('heading')->label('Заголовок')
->schema([
TextInput::make('id')->hidden()->integer()->default(rand(2335235,324634264263426)),
TextInput::make('content')
->label('')
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string $state, Forms\Set $set, $get) {
}),
]),
Builder\Block::make('paragraph')
->schema([
RichEditor::make('content')
->toolbarButtons([
'blockquote',
'bold',
'bulletList',
'italic',
'link',
'orderedList',
'redo',
'strike',
'underline',
'undo',
])
->label(''),
])->label('Текст'),
Builder\Block::make('files')
->schema([
Forms\Components\Repeater::make('file')->schema([
->maxLength(255),
Forms\Components\Repeater::make('steps')->schema([
TextInput::make('title')
->required()
->maxLength(255)->columnSpanFull(),
RichEditor::make('content')->required(),
])->minItems(1),
]),
Builder\Block::make('tabs')
->schema([
Forms\Components\Repeater::make('tab')->schema([
TextInput::make('title')
->required()
->maxLength(255)->columnSpanFull(),
\Filament\Forms\Components\Builder::make('content')->label('')->blocks([
Builder\Block::make('heading')->label('Заголовок')
->schema([
TextInput::make('id')->hidden()->integer()->default(rand(2335235,324634264263426)),
TextInput::make('content')
->label('')
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string $state, Forms\Set $set, $get) {
}),
]),
Builder\Block::make('paragraph')
->schema([
RichEditor::make('content')
->toolbarButtons([
'blockquote',
'bold',
'bulletList',
'italic',
'link',
'orderedList',
'redo',
'strike',
'underline',
'undo',
])
->label(''),
])->label('Текст'),
Builder\Block::make('files')
->schema([
Forms\Components\Repeater::make('file')->schema([
TextInput::make('title')
->required()
->maxLength(255)
->autofocus(),
FileUpload::make('path')
->required()
->acceptedFileTypes([
'application/pdf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/zip'
])
->maxSize(512000)
->disk('public')
->directory('files')
->downloadable()
->visibility('public')
]),
]),
Builder\Block::make('person')
->schema([
TextInput::make('name')
->label('Имя')
->required()
->maxLength(255),
FileUpload::make('photo')
->label('Фотография')
->image()
->disk('public')
->directory('images')
->imageEditor(),
Forms\Components\Repeater::make('info')->schema([
Forms\Components\Grid::make(2)->schema([
TextInput::make('column')
->required()
->maxLength(255),
TextInput::make('content')
->required()
->maxLength(255),
]),
])->minItems(1),
]),
Builder\Block::make('stepper')
->schema([
TextInput::make('step_name')
->label('Название шага')
->required()
->maxLength(255),
Forms\Components\Repeater::make('steps')->schema([
TextInput::make('title')
->required()
->maxLength(255)->columnSpanFull(),
RichEditor::make('content')->required(),
])->minItems(1),
]),
Builder\Block::make('images')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
])->label('Слайдер изображений'),
Builder\Block::make('image')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
])->label('Изображение'),
Builder\Block::make('video')
->schema([
TextInput::make('mime')->readOnly(),
TextInput::make('title')
->required()
->maxLength(255)
@@ -202,220 +309,136 @@ class AdditionalEducationResource extends Resource
FileUpload::make('path')
->required()
->acceptedFileTypes([
'application/pdf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/zip'
'video/mp4',
'video/quicktime',
'video/x-msvideo',
'video/x-ms-wmv',
'video/avi',
'video/webm',
'video/ogg',
'video/3gpp',
'video/3gpp2',
'video/x-m4v',
])
->maxSize(512000)
->disk('public')
->directory('files')
->downloadable()
->visibility('public')
->directory('videos')
->afterStateUpdated(fn (callable $set, $state) => $set('mime', $state?->getMimeType())),
]),
]),
Builder\Block::make('person')
->schema([
TextInput::make('name')
->label('Имя')
->required()
->maxLength(255),
FileUpload::make('photo')
->label('Фотография')
->image()
->disk('public')
->directory('images')
->imageEditor(),
Forms\Components\Repeater::make('info')->schema([
Builder\Block::make('postsList')
->schema([
Forms\Components\Grid::make(2)->schema([
TextInput::make('column')
->required()
->maxLength(255),
TextInput::make('content')
->required()
->maxLength(255),
TextInput::make('count')
->label('Количество запией')
->integer(),
Select::make('category')
->options(Category::all()->pluck('title', 'id'))
]),
])->minItems(1),
]),
Builder\Block::make('stepper')
->schema([
TextInput::make('step_name')
->label('Название шага')
->required()
->maxLength(255),
Forms\Components\Repeater::make('steps')->schema([
TextInput::make('title')
->required()
->maxLength(255)->columnSpanFull(),
RichEditor::make('content')->required(),
])->minItems(1),
]),
Builder\Block::make('images')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
])->label('Слайдер изображений'),
Builder\Block::make('image')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
])->label('Изображение'),
Builder\Block::make('video')
->schema([
TextInput::make('mime')->readOnly(),
TextInput::make('title')
->required()
->maxLength(255)
->autofocus(),
FileUpload::make('path')
->required()
->acceptedFileTypes([
'video/mp4',
'video/quicktime',
'video/x-msvideo',
'video/x-ms-wmv',
'video/avi',
'video/webm',
'video/ogg',
'video/3gpp',
'video/3gpp2',
'video/x-m4v',
])
->disk('public')
->directory('videos')
->afterStateUpdated(fn (callable $set, $state) => $set('mime', $state?->getMimeType())),
]),
Builder\Block::make('postsList')
->schema([
Forms\Components\Grid::make(2)->schema([
TextInput::make('count')
->label('Количество запией')
->integer(),
Select::make('category')
->options(Category::all()->pluck('title', 'id'))
]),
])->label('Список новостей'),
])
->collapsed()
->blockNumbers(false)
->collapsible()
->addActionLabel('Добавить новый блок'),
])->minItems(1),
]),
Builder\Block::make('images')->label('Слайдер изображений')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
]),
Builder\Block::make('image')->label('Изображение')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
]),
Builder\Block::make('video')->label('Видео')
->schema([
TextInput::make('mime')->readOnly(),
TextInput::make('title')
->required()
->maxLength(255)
->autofocus(),
FileUpload::make('path')
->required()
->acceptedFileTypes([
'video/mp4',
'video/quicktime',
'video/x-msvideo',
'video/x-ms-wmv',
'video/avi',
'video/webm',
'video/ogg',
'video/3gpp',
'video/3gpp2',
'video/x-m4v',
])
->disk('public')
->directory('videos')
->afterStateUpdated(fn (callable $set, $state) => $set('mime', $state?->getMimeType())),
]),
Builder\Block::make('postsList')->label('Список новостей')
->schema([
Forms\Components\Grid::make(2)->schema([
TextInput::make('count')
->label('Количество запией')
->integer(),
Select::make('category')
->options(Category::all()->pluck('title', 'id'))
])->label('Список новостей'),
])
->collapsed()
->blockNumbers(false)
->collapsible()
->addActionLabel('Добавить новый блок'),
])->minItems(1),
]),
]),
Builder\Block::make('postItem')->label('Новость')
->schema([
Select::make('post')
->options(Post::query()->where('status', PostStatus::PUBLISHED)->pluck('title', 'id'))
->searchable()
->required(),
]),
Builder\Block::make('pageItem')->label('Страница')
->schema([
Select::make('page')
->options(Page::query()->where('title', '!=' , null)->where('is_visible', true)->pluck('title', 'id'))
->searchable()
->required(),
]),
])
->collapsed()
->blockNumbers(false)
->collapsible()
->blockPickerColumns(3)
->blockPickerWidth('2xl')
->addActionLabel('Добавить новый блок'),
]),
]),
Builder\Block::make('images')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
])->label('Слайдер изображений'),
Builder\Block::make('image')
->schema([
FileUpload::make('url')
->label('Изображение(-я)')
->image()
->multiple()
->reorderable()
->maxFiles(5)
->disk('public')
->directory('images')
->imageEditor()
->required(),
TextInput::make('alt')
->label('Описание')
->placeholder('Необязяательно')
])->label('Изображение'),
Builder\Block::make('video')
->schema([
TextInput::make('mime')->readOnly(),
TextInput::make('title')
->required()
->maxLength(255)
->autofocus(),
FileUpload::make('path')
->required()
->acceptedFileTypes([
'video/mp4',
'video/quicktime',
'video/x-msvideo',
'video/x-ms-wmv',
'video/avi',
'video/webm',
'video/ogg',
'video/3gpp',
'video/3gpp2',
'video/x-m4v',
])
->disk('public')
->directory('videos')
->afterStateUpdated(fn (callable $set, $state) => $set('mime', $state?->getMimeType())),
]),
Builder\Block::make('postsList')
->schema([
Forms\Components\Grid::make(2)->schema([
TextInput::make('count')
->label('Количество запией')
->integer(),
Select::make('category')
->options(Category::all()->pluck('title', 'id'))
]),
])->label('Список новостей'),
Builder\Block::make('postItem')
->schema([
Select::make('post')
->options(Post::query()->where('status', PostStatus::PUBLISHED)->pluck('title', 'id'))
->searchable()
->required(),
])->label('Новость'),
Builder\Block::make('pageItem')
->schema([
Select::make('page')
->options(Page::query()->where('title', '!=' , null)->where('is_visible', true)->pluck('title', 'id'))
->searchable()
->required(),
])->label('Страница'),
Builder\Block::make('customForm')
->schema([
Select::make('form')
->options(CustomForm::query()->where('status', CustomFormStatus::PUBLISHED)->pluck('title', 'form_id'))
->searchable()
->required(),
])->label('Форма'),
])
->collapsed()
->blockNumbers(false)
->collapsible()
->blockPickerColumns(3)
->blockPickerWidth('2xl')
->addActionLabel('Добавить новый блок'),
]),
]),
]),
]);
}
@@ -423,7 +446,9 @@ class AdditionalEducationResource extends Resource
{
return $table
->columns([
//
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('title')->searchable()->sortable(),
Tables\Columns\ToggleColumn::make('is_active'),
])
->filters([
//
@@ -5,8 +5,100 @@ namespace App\Filament\Resources\AdditionalEducationResource\Pages;
use App\Filament\Resources\AdditionalEducationResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Support\Str;
class CreateAdditionalEducation extends CreateRecord
{
protected static string $resource = AdditionalEducationResource::class;
protected function mutateFormDataBeforeCreate(array $data): array
{
$this->seoData = $this->generateSeo($data);
return $data;
}
protected function afterCreate(): void
{
$this->record->seo()->create($this->seoData);
}
private function generateSeo(array $data) : array
{
$title = $data['title'];
$rowData = $this->getFirstBlockByName('paragraph', $data['content']);
$description = strip_tags($rowData['data']['content']);
// $image = ($data['preview'] !== null) ? $data['preview'] : null;
return [
'title' => $title,
'description' => Str::limit($description, 160),
'image' => "",
];
}
private function getFirstBlockByName(string $name, array $content) : array|null
{
$data = null;
foreach ($content as $block) {
$data = ($block['type'] === $name) ? $block : null;
break;
}
return $data;
}
private function getBlockBySeoActiveState(string $name, array $content) : array|null
{
$data = [];
foreach ($content as $block) {
if ($block['type'] === $name) {
$data[] = $block;
}
}
$block = null;
foreach ($data as $item) {
if ($item['data']['seo_active'] === true) {
$block = $item;
}
}
return $block;
}
private function getDataFromBlocks($block) : string
{
$data = "";
switch ($block['type']) {
case 'paragraph':
$data .= strip_tags($block['data']['content']) . " ";
break;
case 'heading':
$data .= strip_tags($block['data']['content']) . " ";
break;
case 'files':
foreach ($block['data']['file'] as $file) {
$data .= $file['title'] . " ";
}
break;
case 'person':
$data .= $block['data']['name'] . " ";
break;
case 'stepper':
$data .= $block['data']['step_name'] . " ";
foreach ($block['data']['steps'] as $step) {
$data .= $step['title'] . " ";
$data .= strip_tags($step['content']) . " ";
}
break;
case 'tabs':
foreach ($block['data']['tab'] as $item) {
foreach ($item['content'] as $block) {
$data .= $this->getDataFromBlocks($block);
};
};
break;
}
return $data;
}
}
@@ -5,11 +5,54 @@ namespace App\Filament\Resources\AdditionalEducationResource\Pages;
use App\Filament\Resources\AdditionalEducationResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Support\Str;
class EditAdditionalEducation extends EditRecord
{
protected static string $resource = AdditionalEducationResource::class;
protected array $seoData;
protected function mutateFormDataBeforeSave(array $data): array
{
$this->seoData = $this->generateSeo($data);
return $data;
}
protected function afterSave(): void
{
$this->record->seo()->update($this->seoData);
}
private function generateSeo(array $data) : array
{
$title = $data['title'];
$rowData = $this->getFirstBlockByName('paragraph', $data['content']);
$description = strip_tags($rowData['data']['content']);
// $image = ($data['preview'] !== null) ? $data['preview'] : null;
return [
'title' => $title,
'description' => Str::limit($description, 160),
'image' => "",
];
}
private function getFirstBlockByName(string $name, array $content) : array|null
{
$data = null;
foreach ($content as $block) {
$data = ($block['type'] === $name) ? $block : null;
break;
}
return $data;
}
protected function getHeaderActions(): array
{
return [
@@ -6,12 +6,14 @@ use App\Filament\Resources\DirectionAdditionalEducationResource\Pages;
use App\Filament\Resources\DirectionAdditionalEducationResource\RelationManagers;
use App\Models\DirectionAdditionalEducation;
use Filament\Forms;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Str;
class DirectionAdditionalEducationResource extends Resource
{
@@ -29,7 +31,13 @@ class DirectionAdditionalEducationResource extends Resource
{
return $form
->schema([
Forms\Components\TextInput::make('title')->required()->columnSpanFull(),
TextInput::make('title')->label('Заголовок')->required()
->live(onBlur: true)
->afterStateUpdated(function (string $operation, string|null $state, Forms\Set $set) {
$set('slug', Str::slug($state));
$set('seo.title', $state);
}),
TextInput::make('slug')->label('Slug')->unique(ignoreRecord: true)->readOnly()->required(),
Forms\Components\Toggle::make('is_active')->columnSpanFull()->inline(false)->default(true),
]);
}
@@ -34,7 +34,6 @@ class EducationalProgramResource extends Resource
protected static ?string $navigationGroup = 'Образование';
protected static ?string $pluralLabel = 'Образовательные программы';
protected static ?string $navigationParentItem = 'Приемная-компания';
@@ -242,7 +241,7 @@ class EducationalProgramResource extends Resource
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('name')->sortable(),
Tables\Columns\TextColumn::make('code_napr'),
Tables\Columns\TextColumn::make('directionStudy.lvl_edu')->limit(30),
])
@@ -43,8 +43,11 @@ class CreatePage extends CreateRecord
{
$title = $data['title'];
$rowData = $this->getFirstBlockByName('paragraph', $data['content']);
$description = strip_tags($rowData['data']['content']);
if ($rowData !== null) {
$description = strip_tags($rowData['data']['content']);
} else {
$description = null;
}
return [
'title' => $title,
'description' => Str::limit($description, 160),
@@ -54,7 +54,11 @@ class EditPage extends EditRecord
{
$title = $data['title'];
$rowData = $this->getFirstBlockByName('paragraph', $data['content']);
$description = strip_tags($rowData['data']['content']);
if ($rowData !== null) {
$description = strip_tags($rowData['data']['content']);
} else {
$description = null;
}
return [
'title' => $title,
@@ -16,6 +16,12 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Support\Str;
use PhpParser\Node\Expr\AssignOp\Mod;
use VK\Client\VKApiClient;
use VK\OAuth\Scopes\VKOAuthGroupScope;
use VK\OAuth\Scopes\VKOAuthUserScope;
use VK\OAuth\VKOAuth;
use VK\OAuth\VKOAuthDisplay;
use VK\OAuth\VKOAuthResponseType;
class CreatePost extends CreateRecord
{
@@ -30,7 +36,6 @@ class CreatePost extends CreateRecord
$data['publish_at'] = $this->setPublishDateTime($data['status']);
$data['search_data'] = $this->generateSearchData($data['content']);
$data['reading_time'] = $this->calculateReadingTime($data['search_data']);
return $data;
}
@@ -44,6 +49,9 @@ class CreatePost extends CreateRecord
{
$title = $data['title'];
$rowData = $this->getBlockBySeoActiveState('paragraph', $data['content']);
if ($rowData === null) {
$rowData = $this->getFirstBlockByName('paragraph', $data['content']);
}
$description = strip_tags($rowData['data']['content']);
$image = ($data['preview'] !== null) ? $data['preview'] : null;
@@ -54,9 +62,13 @@ class CreatePost extends CreateRecord
];
}
private function setPreviewText(array $data) : string
{
$rowData = $this->getBlockBySeoActiveState('paragraph', $data['content']);
if ($rowData === null) {
$rowData = $this->getFirstBlockByName('paragraph', $data['content']);
}
$preview_text = strip_tags($rowData['data']['content']);
return Str::limit($preview_text, 160);
}
@@ -35,6 +35,9 @@ class EditPost extends EditRecord
private function setPreviewText(array $data) : string
{
$rowData = $this->getBlockBySeoActiveState('paragraph', $data['content']);
if ($rowData === null) {
$rowData = $this->getFirstBlockByName('paragraph', $data['content']);
}
$preview_text = strip_tags($rowData['data']['content']);
return Str::limit($preview_text, 160);
}
@@ -61,7 +64,10 @@ class EditPost extends EditRecord
private function generateSeo(array $data) : array
{
$title = $data['title'];
$rowData = $this->getFirstBlockByName('paragraph', $data['content']);
$rowData = $this->getBlockBySeoActiveState('paragraph', $data['content']);
if ($rowData === null) {
$rowData = $this->getFirstBlockByName('paragraph', $data['content']);
}
$description = strip_tags($rowData['data']['content']);
$image = ($this->record->preview !== null) ? $this->record->preview : null;
@@ -2,6 +2,8 @@
namespace App\Http\Controllers;
use App\Enums\FormEducation;
use App\Http\Resources\AdditionalEducationCategoryPreviewResource;
use App\Http\Resources\AdditionalEducationCategoryResource;
use App\Http\Resources\AdditionalEducationResource;
use App\Http\Resources\DirectionAdditionalEducationResource;
@@ -15,30 +17,87 @@ class ClientAdditionalEducationController extends Controller
{
public function index(Request $request)
{
$directionAdditionalEducations = DirectionAdditionalEducationResource::collection(
DirectionAdditionalEducation::query()
->where('is_active', true)
->whereHas('additionalEducationCategories', function ($q) {
$q->whereHas('additionalEducations');
})
->get());
})->get());
$additionalEducations = AdditionalEducationCategoryResource::collection(AdditionalEducationCategory::query()
->WithActivePrograms()
->where('is_active', '=', true)
->when($request->input('dir_id'), function ($q, $direction_id) {
$q->where('dir_addit_educat_id', $direction_id);
->when($request->input('direction'), function ($q, $direction) {
$q->whereHas('direction', function ($query) use ($direction) {
$query->where('slug', $direction);
});
})
->when(request()->input('form'), function ($query, $form) {
$query->whereHas('additionalEducations', function ($q) use ($form) {
$q->where('form_education', FormEducation::fromName($form));
});
$query->with(['additionalEducations' => function ($q) use ($form) {
$q->where('form_education', FormEducation::fromName($form));
}]);
})
->when(request()->input('category'), function ($query) {
$slugs = request()->input('category');
if (is_array($slugs)) {
$query->whereIn('slug', $slugs);
}
})
->has('additionalEducations')
->with('additionalEducations')
->get());
$categories = AdditionalEducationCategoryPreviewResource::collection(
AdditionalEducationCategory::query()
->where('is_active', true)
->has('additionalEducations')
->get()
);
$categoriesContent = [];
if (request()->input('category')) {
foreach (request()->input('category') as $item) {
$categoriesContent[$item] = new AdditionalEducationCategoryResource(AdditionalEducationCategory::where('slug', $item)->first());
}
}
$forms_education = [];
foreach (FormEducation::cases() as $case) {
$forms_education[$case->name] = $case->getLabel();
}
$filters = [
'dir_id' => request()->input('dir_id')
'direction_filter' => [
'type' => 'direction',
'value' => request()->input('direction'),
'param' => 'direction'
],
'form_education_filter' => [
'type' => 'form',
'value' => request()->input('form'),
'param' => 'form'
],
'category_filter' => [
'type' => 'category',
'value' => request()->input('category'),
'param' => 'category',
'content' => $categoriesContent,
],
];
return Inertia::render('Client/Additional-educations/Index', compact('directionAdditionalEducations', 'additionalEducations', 'filters'));
return Inertia::render('Client/Additional-educations/Index',
compact(
'directionAdditionalEducations',
'additionalEducations',
'filters',
'forms_education',
'categories'
));
}
public function show(string $id)
public function show(string $slug)
{
$additionalEducation = new AdditionalEducationResource(AdditionalEducation::query()->with('category.direction')->find($id));
$additionalEducation = new AdditionalEducationResource(AdditionalEducation::query()->with('category.direction')->where('slug', $slug)->first());
return Inertia::render('Client/Additional-educations/Show', compact('additionalEducation'));
}
}
@@ -58,6 +58,7 @@ class ClientPostController extends Controller
->withQueryString());
$categories = CategoryResource::collection(Category::has('posts')->get());
$categoriesContent = [];
if (request()->input('category')) {
foreach (request()->input('category') as $item) {
@@ -111,9 +111,9 @@ class ClientProgramController extends Controller
));
}
public function show($id)
public function show(string $slug)
{
$program = new EducationalProgramFullResource(EducationalProgram::query()->where('id', $id)->with(['admission_plans', 'directionStudy'])->first());
$program = new EducationalProgramFullResource(EducationalProgram::query()->where('slug', $slug)->with(['admission_plans', 'directionStudy'])->first());
$formsEducational = BudgetEducation::cases();
$formsEducational = collect($formsEducational);
$formsEdu = $formsEducational->mapWithKeys(function ($formEducational) {
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers;
use App\Enums\PostStatus;
use App\Http\Resources\AdditionalEducationSearchResource;
use App\Http\Resources\PostThumbnailResource;
use App\Models\AdditionalEducation;
use App\Models\Post;
use Illuminate\Http\Request;
class ClientWidgetAdditionalEducationalProgramController extends Controller
{
public function index()
{
return AdditionalEducationSearchResource::collection(
AdditionalEducation::query()
->where('is_active', true)
->orderBy('title', 'desc')
->get());
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers;
use App\Enums\EducationalProgramStatus;
use App\Http\Resources\EducationalProgramSearchResource;
use App\Models\EducationalProgram;
use Illuminate\Http\Request;
class ClientWidgetEducationalProgramController extends Controller
{
public function index()
{
return EducationalProgramSearchResource::collection(
EducationalProgram::query()
->where('status', EducationalProgramStatus::PUBLISHED)
->orderBy('name', 'desc')
->get());
}
}
@@ -12,7 +12,6 @@ class ClientWidgetPostController extends Controller
{
public function index()
{
return PostThumbnailResource::collection(
Post::query()
->where('status', PostStatus::PUBLISHED)
+6 -3
View File
@@ -4,6 +4,9 @@ namespace App\Http\Controllers;
use App\Http\Requests\Page\StoreRequest;
use App\Http\Requests\Page\UpdateRequest;
use App\Http\Resources\ClientBreadcrumbPage;
use App\Http\Resources\ClientBreadcrumbSection;
use App\Http\Resources\ClientBreadcrumbSubSection;
use App\Http\Resources\ClientNavigationResource;
use App\Http\Resources\MainSectionResource;
use App\Http\Resources\PageResource;
@@ -45,9 +48,9 @@ class PageController extends Controller
if (isset($page->section)) {
$subSectionPages = PageResource::collection($page->section->pages);
$breadcrumbs = [
'mainSection' => $page->section->mainSection->title,
'subSection' => $page->section->title,
'page' => $page->title,
'mainSection' => new ClientBreadcrumbSection($page->section->mainSection),
'subSection' => new ClientBreadcrumbSubSection($page->section),
'page' => new ClientBreadcrumbPage($page),
];
} else {
$subSectionPages = null;
+48
View File
@@ -0,0 +1,48 @@
<?php
namespace App\Http\Controllers;
use App\Services\VK\VkService;
use Illuminate\Http\Request;
use VK\Client\VKApiClient;
use VK\OAuth\Scopes\VKOAuthUserScope;
use VK\OAuth\VKOAuth;
use VK\OAuth\VKOAuthDisplay;
use VK\OAuth\VKOAuthResponseType;
class VkPostController extends Controller
{
private string $wall_token;
private VkService $vkService;
public function __construct()
{
$this->vkService = new VkService(new VKApiClient());
$this->wall_token = env('WALL_ACCESS_VK_TOKEN');
}
public function index()
{
$oauth = new VKOAuth();
$client_id = 52468445;
$redirect_uri = 'https://crawdad-fresh-bream.ngrok-free.app/';
$display = VKOAuthDisplay::PAGE;
$scope = array(VKOAuthUserScope::WALL, VKOAuthUserScope::PHOTOS);
$state = 'dJZ3N05uZc9jpcEgxD6y';
$groups_ids = array(227826614);
$browser_url = $oauth->getAuthorizeUrl(VKOAuthResponseType::TOKEN, $client_id, $redirect_uri, $display, $scope, $state, $groups_ids);
return redirect($browser_url);
}
public function wall()
{
return $this->vkService->createAlbum('Тестовый альбом');
}
}
+2 -5
View File
@@ -2,14 +2,10 @@
namespace App\Http\Middleware;
use App\Models\MainChapter;
use App\Models\MainSection;
use App\Models\Page;
use App\Models\RegisteredRoute;
use App\Models\SubChapter;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Symfony\Component\HttpFoundation\Response;
class AccessCheck
@@ -21,6 +17,7 @@ class AccessCheck
*/
public function handle(Request $request, Closure $next): Response
{
// Проверяем, существует ли запись для текущего маршрута
$registeredRoute = Page::where('path', '=', $request->route()->uri)
->where('is_registered', '=', true)
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class AdditionalEducationCategoryPreviewResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
];
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class AdditionalEducationSelectResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ClientBreadcrumbPage extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'title' => $this->title,
'slug' => $this->slug,
'path' => $this->path
];
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ClientBreadcrumbSection extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'title' => $this->title,
'slug' => $this->slug,
];
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ClientBreadcrumbSubSection extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'title' => $this->title,
'slug' => $this->slug,
];
}
}
@@ -17,6 +17,7 @@ class ClientNavigationResource extends JsonResource
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
'subSections' => ClientSubSectionNavigateResource::collection($this->whenLoaded('subSections')->sortBy('sort')),
];
}
@@ -17,6 +17,7 @@ class ClientSubSectionNavigateResource extends JsonResource
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
'pages' => ClientPageNavigateResource::collection($this->whenLoaded('pages')),
];
}
@@ -17,6 +17,7 @@ class DirectionAdditionalEducationResource extends JsonResource
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
];
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class EducationProgramSelectResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}
@@ -17,6 +17,7 @@ class EducationalProgramResource extends JsonResource
return [
'id' => $this->id,
'name' => $this->name,
'slug' => $this->slug
];
}
}
@@ -2,6 +2,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@@ -11,6 +12,13 @@ class AdditionalEducationCategory extends Model
protected $guarded = false;
public function scopeWithActivePrograms(Builder $query)
{
return $query->with(['additionalEducations' => function ($query) {
$query->where('is_active', true);
}]);
}
public function additionalEducations()
{
return $this->hasMany(AdditionalEducation::class, 'category_id', 'id');
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace App\Services\VK\Album;
use Illuminate\Support\Facades\Log;
use VK\Client\VKApiClient;
class VkAlbumService
{
private VKApiClient $vk;
private string $wallToken;
private string $serviceToken;
private string $publicId;
private string $publicDomain;
public function __construct(VKApiClient $vk) {
$this->vk = $vk;
$this->wallToken = env('WALL_ACCESS_VK_TOKEN');
$this->serviceToken = env('SERVICE_ACCESS_VK_KEY');
$this->publicId = env('PUBLIC_ID');
$this->publicDomain = env('PUBLIC_DOMAIN');
}
public function getServerForUploadImages()
{
return $this->vk->photos()->getUploadServer($this->wallToken, array(
''
));
}
public function createAlbum(string $title)
{
try {
return $this->vk->photos()->createAlbum($this->wallToken, array(
'title' => $title,
'group_id' => $this->publicId,
'privacy' => 0,
));
} catch (\Exception $e) {
Log::error('Ошибка при создании альбома: ' . $e->getMessage());
return [
'success' => false,
'message' => 'Не удалось создать альбом: ' . $e->getMessage(),
];
}
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace App\Services\VK;
use App\Services\VK\Album\VkAlbumService;
use App\Services\VK\Wall\VkWallService;
use VK\Client\VKApiClient;
class VkService
{
protected VkWallService $wallService;
protected VkAlbumService $albumService;
public function __construct(VKApiClient $vk) {
$this->wallService = new VkWallService($vk);
$this->albumService = new VkAlbumService($vk);
}
public function getPosts(int $count = 10)
{
return $this->wallService->getPosts($count);
}
public function createPost(string $message, int $from_group = 1)
{
return $this->wallService->createPost($message, $from_group);
}
public function createAlbum(string $title)
{
return $this->albumService->createAlbum($title);
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
namespace App\Services\VK\Wall;
use Illuminate\Support\Facades\Log;
use VK\Client\VKApiClient;
class VkWallService
{
private VKApiClient $vk;
private string $wallToken;
private string $serviceToken;
private string $publicId;
private string $publicDomain;
public function __construct(VKApiClient $vk) {
$this->vk = $vk;
$this->wallToken = env('WALL_ACCESS_VK_TOKEN');
$this->serviceToken = env('SERVICE_ACCESS_VK_KEY');
$this->publicId = env('PUBLIC_ID');
$this->publicDomain = env('PUBLIC_DOMAIN');
}
public function getPosts(int $count)
{
return $this->vk->wall()->get($this->serviceToken, array(
'owner_id' => '-'. $this->publicId,
'domain' => $this->publicDomain,
'count' => $count
));
}
public function createPost(string $message, int $from_group, string $attachments = '')
{
try {
return $this->vk->wall()->post($this->wallToken, array(
'owner_id' => '-' . $this->publicId,
'from_group' => $from_group,
'message' => $message,
'attachments' => $attachments
));
} catch (\Exception $e) {
Log::error('Ошибка при создании поста: ' . $e->getMessage());
return [
'success' => false,
'message' => 'Не удалось создать пост: ' . $e->getMessage(),
];
}
}
}