Skip to content

Commit

Permalink
Added wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jaxwilko committed Dec 6, 2024
1 parent abdb18f commit b80e34f
Show file tree
Hide file tree
Showing 9 changed files with 355 additions and 50 deletions.
35 changes: 35 additions & 0 deletions modules/cms/classes/Theme.php
Original file line number Diff line number Diff line change
Expand Up @@ -714,4 +714,39 @@ public function __isset($key)

return false;
}

public function extensionInstall(): static
{
// TODO: Implement extensionInstall() method.
}

public function extensionUninstall(): static
{
// TODO: Implement extensionUninstall() method.
}

public function extensionEnable(): static
{
// TODO: Implement extensionEnable() method.
}

public function extensionDisable(): static
{
// TODO: Implement extensionDisable() method.
}

public function extensionRollback(): static
{
// TODO: Implement extensionRollback() method.
}

public function extensionRefresh(): static
{
// TODO: Implement extensionRefresh() method.
}

public function extensionUpdate(): static
{
// TODO: Implement extensionUpdate() method.
}
}
20 changes: 13 additions & 7 deletions modules/cms/classes/ThemeManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

namespace Cms\Classes;

use Winter\Storm\Support\Facades\File;
use System\Classes\Extensions\WinterExtension;
use Winter\Storm\Exception\ApplicationException;
use Cms\Classes\Theme;
use System\Classes\Extensions\ExtensionManager;
use System\Classes\Extensions\ExtensionSource;
use System\Classes\Extensions\WinterExtension;
use System\Models\Parameter;
use Cms\Classes\Theme;
use Winter\Storm\Exception\ApplicationException;
use Winter\Storm\Support\Facades\File;

/**
* Theme manager
Expand All @@ -33,7 +34,7 @@ public function getInstalled()
* @param string $name Theme code
* @return boolean
*/
public function isInstalled($name)
public function isInstalled($name): bool
{
return array_key_exists($name, Parameter::get('system::theme.history', []));
}
Expand Down Expand Up @@ -95,12 +96,17 @@ public function create(): Theme
// TODO: Implement create() method.
}

public function install(Theme|string $extension): Theme
public function install(ExtensionSource|WinterExtension|string $extension): Theme
{
// TODO: Implement install() method.
}

public function enable(Theme|string $extension): Theme
public function getExtension(WinterExtension|ExtensionSource|string $extension): ?WinterExtension
{
// TODO: Implement getExtension() method.
}

public function enable(WinterExtension|string $extension): Theme
{
// TODO: Implement enable() method.
}
Expand Down
6 changes: 5 additions & 1 deletion modules/system/classes/extensions/ExtensionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@

interface ExtensionManager
{
public const EXTENSION_NAME = '';

public function list(): array;

public function create(): WinterExtension;
/**
* @throws ApplicationException If the installation fails
*/
public function install(WinterExtension|string $extension): WinterExtension;
public function install(ExtensionSource|WinterExtension|string $extension): WinterExtension;
public function isInstalled(ExtensionSource|WinterExtension|string $extension): bool;
public function getExtension(ExtensionSource|WinterExtension|string $extension): ?WinterExtension;
public function enable(WinterExtension|string $extension): mixed;
public function disable(WinterExtension|string $extension): mixed;
public function update(WinterExtension|string $extension): mixed;
Expand Down
203 changes: 203 additions & 0 deletions modules/system/classes/extensions/ExtensionSource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
<?php

namespace System\Classes\Extensions;

use Cms\Classes\ThemeManager;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\File;
use System\Classes\Packager\Composer;
use Winter\Packager\Exceptions\CommandException;
use Winter\Storm\Exception\ApplicationException;
use Winter\Storm\Support\Str;

class ExtensionSource
{
public const SOURCE_COMPOSER = 'composer';
public const SOURCE_MARKET = 'market';
public const SOURCE_LOCAL = 'local';

public const TYPE_PLUGIN = 'plugin';
public const TYPE_THEME = 'theme';
public const TYPE_MODULE = 'module';

public const STATUS_UNINSTALLED = 'uninstalled';
public const STATUS_INSTALLED = 'installed';
public const STATUS_UNPACKED = 'unpacked';

protected array $extensionManagerMapping = [
self::TYPE_PLUGIN => PluginManager::class,
self::TYPE_THEME => ThemeManager::class,
self::TYPE_MODULE => ModuleManager::class,
];

protected string $status = 'uninstalled';

public function __construct(
public string $source,
public string $type,
public ?string $code = null,
public ?string $composerPackage = null,
public ?string $path = null
) {
if (!in_array($this->source, [static::SOURCE_COMPOSER, static::SOURCE_MARKET, static::SOURCE_LOCAL])) {
throw new \InvalidArgumentException("Invalid source '{$this->source}'");
}

if (!in_array($this->type, [static::TYPE_PLUGIN, static::TYPE_THEME, static::TYPE_MODULE])) {
throw new \InvalidArgumentException("Invalid type '{$this->type}'");
}

if ($this->source === static::SOURCE_COMPOSER && !$this->composerPackage) {
throw new ApplicationException('You must provide a composer package for a composer source.');
}

if ($this->source !== static::SOURCE_COMPOSER && !$this->code) {
if (!$this->path) {
throw new ApplicationException('You must provide a code or path.');
}

$this->code = $this->guessCodeFromPath($this->path);
}

$this->status = $this->checkStatus();
}

public function getStatus(): string
{
return $this->status;
}

public function getCode(): ?string
{
if ($this->code) {
return $this->code;
}

if (!$this->path) {
return null;
}

return $this->code = $this->guessCodeFromPath($this->path);
}

/**
* @throws ApplicationException
*/
public function createFiles(): static
{
switch ($this->source) {
case static::SOURCE_COMPOSER:
try {
Composer::require($this->composerPackage);
} catch (CommandException $e) {
throw new ApplicationException('Unable to require composer package', previous: $e);
}

$info = Composer::show('installed', $this->composerPackage);
$this->path = $this->relativePath($info['path']);
$this->source = static::SOURCE_LOCAL;
break;
case static::SOURCE_MARKET:
throw new ApplicationException('need to implement market support');
break;
case static::SOURCE_LOCAL:
break;
}

if ($this->status !== static::STATUS_INSTALLED) {
$this->status = static::STATUS_UNPACKED;
}

return $this;
}

/**
* @throws ApplicationException
*/
public function install(): WinterExtension
{
if ($this->status === static::STATUS_UNINSTALLED) {
throw new ApplicationException('Extension source is not unpacked');
}

if ($this->status === static::STATUS_INSTALLED) {
return $this->getExtensionManager()->getExtension($this);
}

return $this->getExtensionManager()->install($this);
}

public function uninstall(): bool
{
if ($this->status !== static::STATUS_INSTALLED) {
throw new ApplicationException('Extension source is not installed');
}

return $this->getExtensionManager()->uninstall($this);
}

protected function getExtensionManager(): ExtensionManager
{
return App::make($this->extensionManagerMapping[$this->type]);
}

protected function checkStatus(): string
{
switch ($this->source) {
case static::SOURCE_COMPOSER:
try {
$info = Composer::show('installed', $this->composerPackage);
} catch (CommandException $e) {
return static::STATUS_UNINSTALLED;
}

$this->path = $this->relativePath($info['path']);

if (!$this->getExtensionManager()->isInstalled($this)) {
return static::STATUS_UNPACKED;
}
break;
case static::SOURCE_MARKET:
case static::SOURCE_LOCAL:
$path = $this->path ?? $this->guessPackagePath($this->code);
if (!File::exists($path)) {
return static::STATUS_UNINSTALLED;
}
break;
}

if (!$this->getExtensionManager()->isInstalled($this)) {
return static::STATUS_UNPACKED;
}

return static::STATUS_INSTALLED;
}

protected function guessPackagePath(string $code): ?string
{
return match ($this->type) {
static::TYPE_PLUGIN => plugins_path(str_replace('.', '/', $code)),
static::TYPE_THEME => themes_path($code),
static::TYPE_MODULE => base_path('modules/' . $code),
default => null,
};
}

protected function guessCodeFromPath(string $path): ?string
{
return match ($this->type) {
static::TYPE_PLUGIN => str_replace('/', '.', ltrim(Str::after($path, basename(plugins_path())), '/')),
static::TYPE_THEME => Str::after($path, themes_path()),
static::TYPE_MODULE => Str::after($path, base_path('modules/')),
default => null,
};
}

protected function relativePath(string $path): string
{
return ltrim(Str::after($path, match ($this->type) {
static::TYPE_PLUGIN, static::TYPE_THEME => base_path(),
static::TYPE_MODULE => base_path('modules'),
}), '/');
}
}
41 changes: 22 additions & 19 deletions modules/system/classes/extensions/ModuleManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,50 @@

namespace System\Classes\Extensions;

class ModuleManager implements WinterExtension
class ModuleManager implements ExtensionManager
{
public function install(): static
public function list(): array
{
// TODO: Implement install() method.
return $this;
// TODO: Implement list() method.
}

public function uninstall(): static
public function create(): WinterExtension
{
// TODO: Implement uninstall() method.
return $this;
// TODO: Implement create() method.
}

public function enable(): static
public function install(WinterExtension|string $extension): WinterExtension
{
// TODO: Implement install() method.
}

public function enable(WinterExtension|string $extension): mixed
{
// TODO: Implement enable() method.
return $this;
}

public function disable(): static
public function disable(WinterExtension|string $extension): mixed
{
// TODO: Implement disable() method.
return $this;
}

public function rollback(): static
public function update(WinterExtension|string $extension): mixed
{
// TODO: Implement rollback() method.
return $this;
// TODO: Implement update() method.
}

public function refresh(): static
public function refresh(WinterExtension|string $extension): mixed
{
// TODO: Implement refresh() method.
return $this;
}

public function update(): static
public function rollback(WinterExtension|string $extension, string $targetVersion): mixed
{
// TODO: Implement update() method.
return $this;
// TODO: Implement rollback() method.
}

public function uninstall(WinterExtension|string $extension): mixed
{
// TODO: Implement uninstall() method.
}
}
Loading

0 comments on commit b80e34f

Please sign in to comment.