This commit is contained in:
Ваше Имя 2025-07-28 14:25:57 +05:00
parent a257f257a0
commit c8224d2455
11 changed files with 330 additions and 50 deletions

21
app/Models/Factory.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace App\Models;
use App\Models\Pages\Factory as PagesFactory;
class Factory
{
private ?PagesFactory $pagesFactory = null;
public function getPagesFactory(): PagesFactory
{
if ($this->pagesFactory) {
return $this->pagesFactory;
}
$this->pagesFactory = new PagesFactory();
$this->pagesFactory->setModelsFactory($this);
return $this->pagesFactory;
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Models\Pages;
use App\Models\Factory as ModelsFactory;
use App\Providers\AppServiceProvider;
use Modules\ModulesProvider;
class Factory
{
private ModelsFactory $modelsFactory;
public function setModelsFactory(ModelsFactory $factory): void
{
$this->modelsFactory = $factory;
}
public function createMainInfoPage(): MainInfo
{
$page = new MainInfo;
/** @var ModulesProvider */
$modulesProvider = app()->get(AppServiceProvider::ADMIN_MODULES);
$itemsStorage = $modulesProvider->getJsonObjectsFactory()->getInfrastructureFactory()->getStorage();
$page->setItemsStorage($itemsStorage);
$itemFactory = $modulesProvider->getJsonObjectsFactory()->getDtoFactory()->getItemFactory();
$page->setItemFactory($itemFactory);
$page->init();
return $page;
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Models\Pages;
use App\Models\Factory as ModelsFactory;
use Src\Modules\JsonObjects\Interfaces\Infrastructure\IItemStorage;
use Src\Modules\JsonObjects\Interfaces\Dto\Item\IFactory as IItemFactory;
use Modules\Objects\MainInfo as MainInfoObject;
class MainInfo
{
private IItemStorage $itemsStorage;
private IItemFactory $itemFactory;
private MainInfoObject $mainInfoObject;
public function setItemsStorage(IItemStorage $storage): void
{
$this->itemsStorage = $storage;
}
public function setItemFactory(IItemFactory $factory): void
{
$this->itemFactory = $factory;
}
public function init(): void
{
$mainInfoData = $this->itemsStorage->getByKey('main_info');
$mainInfo = $this->itemFactory->createResource();
$mainInfo->load($mainInfoData);
$this->mainInfoObject = $mainInfo->getObject();
}
public function getMainInfo(): MainInfoObject
{
return $this->mainInfoObject;
}
}

View File

@ -1,48 +0,0 @@
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}

View File

@ -4,11 +4,14 @@ namespace App\Providers;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Modules\ModulesProvider as AdminModulesProvider; use Modules\ModulesProvider as AdminModulesProvider;
use App\Models\Factory as ModelsFactory;
class AppServiceProvider extends ServiceProvider class AppServiceProvider extends ServiceProvider
{ {
const ADMIN_MODULES = 'admin_modules'; const ADMIN_MODULES = 'admin_modules';
const MODELS_FACTORY = 'models-factory';
/** /**
* Register any application services. * Register any application services.
*/ */
@ -28,5 +31,10 @@ class AppServiceProvider extends ServiceProvider
$provider->init(); $provider->init();
return $provider; return $provider;
}); });
$this->app->singleton(self::MODELS_FACTORY, function ($app) {
$factory = new ModelsFactory();
return $factory;
});
} }
} }

View File

@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use App\Providers\AppServiceProvider;
use Src\Modules\JsonObjects\Interfaces\IFactory;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
/** @var IFactory */
$factory = app(AppServiceProvider::ADMIN_MODULES)->getJsonObjectsFactory();
$item = $factory->getDtoFactory()->getItemFactory()->createPersist(\Modules\Objects\MainInfo::TYPE);
$item->load(['key' => 'main_info', 'name' => 'Main info', 'disabled' => 1]);
$attrs = $item->getInsertAttrs();
DB::table('json_items')->insert($attrs);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
DB::table('json_items')->where('key', '=', 'main_info')->delete();
}
};

View File

@ -3,5 +3,15 @@
namespace Modules; namespace Modules;
use Src\ModulesProvider as BaseProvider; use Src\ModulesProvider as BaseProvider;
use Modules\Objects\Factory as ObjectsFactory;
use Src\Modules\JsonObjects\Interfaces\IFactory as IJSONFactory;
class ModulesProvider extends BaseProvider {} class ModulesProvider extends BaseProvider
{
public function init(array $conf = []): void
{
$conf['jsonObjects']['settings'][IJSONFactory::OBJECTS_FACTORY] = new ObjectsFactory;
parent::init($conf);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace Modules\Objects;
use Src\Common\Interfaces\Dto\Object\IFactory;
use Src\Common\Dto\Object\Factory as Base;
use Src\Common\Dto\Object\AbstractObject;
class Factory extends Base implements IFactory
{
public function createObjectField(string $type): ?AbstractObject
{
if ($type == MainInfo::TYPE) {
$object = new MainInfo();
$object->setFieldsFactory($this);
$object->init();
return $object;
}
return parent::createObjectField($type);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace Modules\Objects;
use Src\Common\Dto\Object\AbstractComposite;
use Src\Common\Dto\Object\ImageObject;
use Src\Common\Dto\Object\StringObject;
use Src\Common\Dto\Object\TextObject;
class MainInfo extends AbstractComposite
{
const TYPE = 'main-info';
public function init()
{
$this->type = self::TYPE;
$this->description = 'Main info';
/** @var ImageObject */
$image = $this->fieldsFactory->createObjectField(AbstractComposite::IMAGE_TYPE);
$image->setDescriptionStr('Image');
$image->setAR(400 / 500);
$image->setPath('/files-browser');
$this->fields['image'] = $image;
/** @var StringObject */
$h1 = $this->fieldsFactory->createObjectField(AbstractComposite::STRING_TYPE);
$h1->setDescriptionStr('H1');
$this->fields['h1'] = $h1;
/** @var StringObject */
$subtitle = $this->fieldsFactory->createObjectField(AbstractComposite::STRING_TYPE);
$subtitle->setDescriptionStr('subtitle');
$this->fields['subtitle'] = $subtitle;
/** @var TextObject */
$text = $this->fieldsFactory->createObjectField(AbstractComposite::HTML_TYPE);
$text->setDescriptionStr('text');
$this->fields['text'] = $text;
}
public function getField(string $field): ?string
{
/** @var ImageObject */
$f = $this->fields[$field];
return $f->getValue();
}
}

View File

@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сайт-визитка</title>
<style>
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
color: #333;
background-color: #f9f9f9;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
}
header {
text-align: center;
padding: 30px 0;
border-bottom: 1px solid #eee;
margin-bottom: 30px;
}
h1 {
color: #2c3e50;
margin-bottom: 10px;
}
.subtitle {
color: #7f8c8d;
font-style: italic;
}
.content {
display: flex;
flex-wrap: wrap;
gap: 30px;
margin-bottom: 40px;
}
.photo {
flex: 1;
min-width: 300px;
text-align: center;
}
.photo img {
max-width: 100%;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.text-block {
flex: 2;
min-width: 300px;
background: white;
padding: 25px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
footer {
text-align: center;
padding: 20px;
color: #7f8c8d;
font-size: 0.9em;
border-top: 1px solid #eee;
}
.contacts {
margin-top: 20px;
}
a {
color: #3498db;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>{{ $page->getMainInfo()->getField('h1') }}</h1>
<p class="subtitle">{{ $page->getMainInfo()->getField('subtitle') }}</p>
</header>
<div class="content">
<div class="photo">
<img src="/files-browser{{ $page->getMainInfo()->getField('image') }}" alt="Мое фото">
</div>
<div class="text-block">
{!! $page->getMainInfo()->getField('text') !!}
</div>
</div>
<footer>
<p>© {{ date('Y') }} Все права защищены.</p>
</footer>
</div>
</body>
</html>

View File

@ -16,5 +16,8 @@ Route::group(['middleware' => [UsersProviderMiddleware::class, AuthMiddleware::c
}); });
Route::get('/', function () { Route::get('/', function () {
return view('welcome'); /** @var \App\Models\Factory */
$factory = app()->get(\App\Providers\AppServiceProvider::MODELS_FACTORY);
$page = $factory->getPagesFactory()->createMainInfoPage();
return view('example', ['page' => $page]);
})->name('home'); })->name('home');