Skip to content

Commit 18173bc

Browse files
committed
WP Site Entity
1 parent 66856d9 commit 18173bc

18 files changed

Lines changed: 947 additions & 0 deletions

File tree

packages/core/resources/lang/de/core.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,15 @@
156156
'translation_create' => 'Übersetzung erstellen',
157157
'publish_main_entry' => 'Haupteintrag veröffentlichen',
158158
'publish_main_entry_description' => 'Diese Aktion veröffentlicht den Haupteintrag.',
159+
'site' => 'Site',
160+
'sites' => 'Sites',
161+
'wp_site_meta' => 'Site Meta',
162+
'wp_site_metas' => 'Site Metas',
163+
'path' => 'Path',
164+
'site_name' => 'Site Name',
165+
'admin_email' => 'Admin Email',
166+
'siteurl' => 'Site URL',
167+
'registration' => 'Registration',
168+
'upload_filetypes' => 'Upload Filetypes',
169+
'site_id' => 'Site ID',
159170
];

packages/core/resources/lang/en/core.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,15 @@
156156
'translation_create' => 'Create translation',
157157
'publish_main_entry' => 'Publish main entry',
158158
'publish_main_entry_description' => 'This action will publish the main entry.',
159+
'site' => 'Site',
160+
'sites' => 'Sites',
161+
'wp_site_meta' => 'Site Meta',
162+
'wp_site_metas' => 'Site Metas',
163+
'path' => 'Path',
164+
'site_name' => 'Site Name',
165+
'admin_email' => 'Admin Email',
166+
'siteurl' => 'Site URL',
167+
'registration' => 'Registration',
168+
'upload_filetypes' => 'Upload Filetypes',
169+
'site_id' => 'Site ID',
159170
];

packages/press/config/press.php

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,74 @@
977977
*/
978978
],
979979
],
980+
981+
'site' => [
982+
983+
/*
984+
|--------------------------------------------------------------------------
985+
| Title
986+
|--------------------------------------------------------------------------
987+
|
988+
| The translatable title of the Resource in singular and plural.
989+
|
990+
*/
991+
992+
'single' => 'trans//core::core.site',
993+
'plural' => 'trans//core::core.sites',
994+
995+
/*
996+
|--------------------------------------------------------------------------
997+
| Tabs
998+
|--------------------------------------------------------------------------
999+
|
1000+
| Define the tabs for the Expiry table. They are optional, but
1001+
| pretty awesome to filter the table by certain values.
1002+
| You may simply do a 'tabs' => [], to disable them.
1003+
|
1004+
*/
1005+
1006+
'tabs' => [
1007+
'all' => [
1008+
'label' => 'trans//core::core.all',
1009+
'icon' => 'gmdi-filter-list',
1010+
'query' => [],
1011+
],
1012+
],
1013+
],
1014+
1015+
'siteMeta' => [
1016+
1017+
/*
1018+
|--------------------------------------------------------------------------
1019+
| Title
1020+
|--------------------------------------------------------------------------
1021+
|
1022+
| The translatable title of the Resource in singular and plural.
1023+
|
1024+
*/
1025+
1026+
'single' => 'trans//core::core.wp_site_meta',
1027+
'plural' => 'trans//core::core.wp_site_metas',
1028+
1029+
/*
1030+
|--------------------------------------------------------------------------
1031+
| Tabs
1032+
|--------------------------------------------------------------------------
1033+
|
1034+
| Define the tabs for the Expiry table. They are optional, but
1035+
| pretty awesome to filter the table by certain values.
1036+
| You may simply do a 'tabs' => [], to disable them.
1037+
|
1038+
*/
1039+
1040+
'tabs' => [
1041+
'all' => [
1042+
'label' => 'trans//core::core.all',
1043+
'icon' => 'gmdi-filter-list',
1044+
'query' => [],
1045+
],
1046+
],
1047+
],
9801048
],
9811049

9821050
/*
@@ -1021,6 +1089,37 @@
10211089

10221090
'wordpress_prefix' => env('WP_PREFIX', 'wp_'),
10231091

1092+
/*
1093+
|--------------------------------------------------------------------------
1094+
| WordPress Multisite
1095+
|--------------------------------------------------------------------------
1096+
|
1097+
| Enable this when your WordPress installation is a multisite network.
1098+
| Only then the WpSite and WpSiteMeta resources are registered.
1099+
| The wpinstall command sets this based on the install type.
1100+
|
1101+
*/
1102+
1103+
'multisite' => env('MULTISITE', false),
1104+
1105+
/*
1106+
|--------------------------------------------------------------------------
1107+
| Site Meta
1108+
|--------------------------------------------------------------------------
1109+
|
1110+
| These are the network meta keys stored in the sitemeta table. Defined
1111+
| keys are editable in the WpSite resource and appended to the model.
1112+
|
1113+
*/
1114+
1115+
'default_site_meta' => [
1116+
'site_name' => '',
1117+
'admin_email' => '',
1118+
'siteurl' => '',
1119+
'registration' => 'none',
1120+
'upload_filetypes' => 'jpg jpeg png gif webp',
1121+
],
1122+
10241123
/*
10251124
|--------------------------------------------------------------------------
10261125
| WordPress Slug

packages/press/src/Commands/InstallWordPress.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,8 @@ public function wpInstall(): void
386386
default: 'multisite',
387387
);
388388

389+
$this->setEnvValue('MULTISITE', $installType === 'multisite' ? 'true' : 'false');
390+
389391
$commonArgs = [
390392
'--url='.$siteUrl,
391393
'--title='.$siteTitle,
@@ -443,6 +445,26 @@ public function wpInstall(): void
443445
$this->installAndActivateDefaultTheme($wpPath);
444446
}
445447

448+
protected function setEnvValue(string $key, string $value): void
449+
{
450+
$envPath = base_path('.env');
451+
452+
if (! File::exists($envPath)) {
453+
return;
454+
}
455+
456+
$contents = (string) file_get_contents($envPath);
457+
$line = $key.'='.$value;
458+
459+
if (preg_match('/^'.preg_quote($key, '/').'=.*$/m', $contents) === 1) {
460+
$contents = (string) preg_replace('/^'.preg_quote($key, '/').'=.*$/m', $line, $contents);
461+
} else {
462+
$contents = rtrim($contents, "\n")."\n".$line."\n";
463+
}
464+
465+
file_put_contents($envPath, $contents);
466+
}
467+
446468
protected function installAndActivateDefaultTheme(string $fullWpPath): void
447469
{
448470
$this->info('Ensuring a default theme is installed and activated...');
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Moox\Press\Models;
6+
7+
use Illuminate\Database\Eloquent\Collection;
8+
use Illuminate\Database\Eloquent\Factories\HasFactory;
9+
use Illuminate\Database\Eloquent\Model;
10+
use Illuminate\Database\Eloquent\Relations\HasMany;
11+
use Override;
12+
13+
/**
14+
* @property int $id
15+
* @property string $domain
16+
* @property string $path
17+
*/
18+
class WpSite extends Model
19+
{
20+
use HasFactory;
21+
22+
/** @var list<string> */
23+
protected $fillable = ['domain', 'path'];
24+
25+
/** @var list<string> */
26+
protected $searchableFields = ['*'];
27+
28+
protected ?string $wpPrefix = null;
29+
30+
protected $table;
31+
32+
protected ?string $metatable = null;
33+
34+
protected $primaryKey = 'id';
35+
36+
public $timestamps = false;
37+
38+
protected bool $metaFieldsInitialized = false;
39+
40+
public function __construct(array $attributes = [])
41+
{
42+
parent::__construct($attributes);
43+
$this->wpPrefix = config('press.wordpress_prefix');
44+
$this->table = $this->wpPrefix.'site';
45+
$this->metatable = $this->wpPrefix.'sitemeta';
46+
$this->metaFieldsInitialized = true;
47+
}
48+
49+
#[Override]
50+
protected static function boot(): void
51+
{
52+
parent::boot();
53+
54+
static::deleted(function (WpSite $model): void {
55+
$model->siteMeta()->delete();
56+
});
57+
}
58+
59+
public function siteMeta(): HasMany
60+
{
61+
return $this->hasMany(WpSiteMeta::class, 'site_id', 'id');
62+
}
63+
64+
#[Override]
65+
public function getAttribute($key)
66+
{
67+
$value = parent::getAttribute($key);
68+
69+
if (is_null($value) && $this->metaFieldsInitialized && $this->isMetaField($key)) {
70+
return $this->getMeta($key);
71+
}
72+
73+
return $value;
74+
}
75+
76+
#[Override]
77+
public function setAttribute($key, $value)
78+
{
79+
if ($this->metaFieldsInitialized && $this->isMetaField($key)) {
80+
$this->addOrUpdateMeta($key, $value);
81+
82+
return $this;
83+
}
84+
85+
return parent::setAttribute($key, $value);
86+
}
87+
88+
public function getMeta(string $key): mixed
89+
{
90+
if (! $this->relationLoaded('siteMeta')) {
91+
$this->load('siteMeta');
92+
}
93+
94+
/** @var Collection<int, WpSiteMeta> $siteMeta */
95+
$siteMeta = $this->siteMeta;
96+
97+
$meta = $siteMeta->where('meta_key', $key)->first();
98+
99+
return $meta instanceof WpSiteMeta ? $meta->meta_value : null;
100+
}
101+
102+
public function addOrUpdateMeta(string $key, mixed $value): void
103+
{
104+
WpSiteMeta::updateOrCreate(
105+
['site_id' => $this->id, 'meta_key' => $key],
106+
['meta_value' => $value]
107+
);
108+
}
109+
110+
/**
111+
* @return array<string, mixed>
112+
*/
113+
public function getAllMetaAttributes(): array
114+
{
115+
$metaFields = config('press.default_site_meta', []);
116+
$attributes = [];
117+
118+
foreach (array_keys($metaFields) as $key) {
119+
$attributes[$key] = $this->getMeta($key);
120+
}
121+
122+
return $attributes;
123+
}
124+
125+
protected function isMetaField(string $key): bool
126+
{
127+
return array_key_exists($key, config('press.default_site_meta', []));
128+
}
129+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Moox\Press\Models;
6+
7+
use Illuminate\Database\Eloquent\Factories\HasFactory;
8+
use Illuminate\Database\Eloquent\Model;
9+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
10+
11+
/**
12+
* @property int $meta_id
13+
* @property int $site_id
14+
* @property string $meta_key
15+
* @property mixed $meta_value
16+
*/
17+
class WpSiteMeta extends Model
18+
{
19+
use HasFactory;
20+
21+
/** @var list<string> */
22+
protected $fillable = ['site_id', 'meta_key', 'meta_value'];
23+
24+
/** @var list<string> */
25+
protected $searchableFields = ['*'];
26+
27+
protected ?string $wpPrefix = null;
28+
29+
protected $table;
30+
31+
protected $primaryKey = 'meta_id';
32+
33+
public $timestamps = false;
34+
35+
public function __construct(array $attributes = [])
36+
{
37+
parent::__construct($attributes);
38+
$this->wpPrefix = config('press.wordpress_prefix');
39+
$this->table = $this->wpPrefix.'sitemeta';
40+
}
41+
42+
public function site(): BelongsTo
43+
{
44+
return $this->belongsTo(WpSite::class, 'site_id', 'id');
45+
}
46+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Moox\Press\Plugins;
6+
7+
use Filament\Contracts\Plugin;
8+
use Filament\Panel;
9+
use Filament\Support\Concerns\EvaluatesClosures;
10+
use Moox\Press\Resources\WpSiteMetaResource;
11+
12+
class WpSiteMetaPlugin implements Plugin
13+
{
14+
use EvaluatesClosures;
15+
16+
public function getId(): string
17+
{
18+
return 'wp-sitemeta';
19+
}
20+
21+
public function register(Panel $panel): void
22+
{
23+
if (config('press.multisite') !== true) {
24+
return;
25+
}
26+
27+
$panel->resources([
28+
WpSiteMetaResource::class,
29+
]);
30+
}
31+
32+
public function boot(Panel $panel): void
33+
{
34+
//
35+
}
36+
37+
public static function make(): static
38+
{
39+
return app(static::class);
40+
}
41+
}

0 commit comments

Comments
 (0)