Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions src/Info.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

namespace Bethropolis\PluginSystem;

use Bethropolis\PluginSystem\System;

class Info
{
private $configFilePath;
private $pluginDir;
private $config;

public function __construct()
{
$this->configFilePath = __DIR__ . '/config/plugins.json';
$this->pluginDir = System::getPluginsDir();
$this->loadConfig();
}

private function loadConfig()
{
if (file_exists($this->configFilePath)) {
$configContents = file_get_contents($this->configFilePath);
$this->config = json_decode($configContents, true);
} else {
$this->config = [
'plugins' => [],
];
$this->saveConfig();
}
}

public function refreshPlugins()
{
$this->config['plugins'] = [];
$plugins = $this->scanPluginsDirectory();

foreach ($plugins as $pluginName) {
$pluginConfigFile = $this->pluginDir . $pluginName . '/plugin.json';
if (file_exists($pluginConfigFile)) {
$pluginConfig = json_decode(file_get_contents($pluginConfigFile), true);
$this->config['plugins'][$pluginName] = $pluginConfig;
}
}

$this->saveConfig();
}

private function scanPluginsDirectory()
{
$plugins = [];
if (is_dir($this->pluginDir)) {
$dirContent = scandir($this->pluginDir);
foreach ($dirContent as $item) {
if ($item !== '.' && $item !== '..' && is_dir($this->pluginDir . $item)) {
$plugins[] = $item;
}
}
}
return $plugins;
}

public function addPlugin($pluginName, $data)
{
if (isset($this->config['plugins'][$pluginName])) {
return;
}

$this->config['plugins'][$pluginName] = $data;
$this->saveConfig();
return true;
}

public function removePlugin($pluginName)
{
unset($this->config['plugins'][$pluginName]);
$this->saveConfig();
}

public function modifyPluginData($pluginName, $data)
{
if (isset($this->config['plugins'][$pluginName])) {
$this->config['plugins'][$pluginName] = array_merge($this->config['plugins'][$pluginName], $data);
$this->saveConfig();
}
}

public function getPlugins()
{
$plugins = $this->config['plugins'] ?? [];
return $plugins;
}

private function saveConfig()
{
$configContents = json_encode($this->config, JSON_PRETTY_PRINT);
file_put_contents($this->configFilePath, $configContents);
}
}
21 changes: 13 additions & 8 deletions src/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,35 +75,41 @@ public static function installPlugin($pluginUrl)
unlink($tempFilePath);
return true;
}

public static function uninstallPlugin($pluginName)
{
$pluginNamespace = __NAMESPACE__ . '\\' . $pluginName . "Plugin\\Load";
$pluginNamespace = stripslashes(strtolower($pluginNamespace));



if (!self::pluginExists($pluginNamespace)) {
return Error::handleException(new \Exception("Plugin does not exist."));
Error::handleException(new \Exception("Plugin does not exist."));
return;
}

self::deactivatePlugin($pluginNamespace); // hard coding it for now

if (self::isPluginActive($pluginNamespace)) {
return Error::handleException(new \Exception("Cannot uninstall an active plugin. Deactivate it first."));
Error::handleException(new \Exception("Cannot uninstall an active plugin. Deactivate it first."));
return;
}

$pluginDir = self::$pluginsDir . '/' . $pluginName;
if (!is_dir($pluginDir)) {
Error::handleException(new \Exception("Plugin directory not found."));
return;
}

if (!self::deleteDirectory($pluginDir)) {
Error::handleException(new \Exception("Unable to remove the plugin directory."));
return;
}

self::unregisterPlugin($pluginNamespace);
self::$lifeCycle->onUninstallation($pluginName);

unset(self::$config['plugins'][$pluginName]);
self::saveConfig();
return true;
}

private static function deleteDirectory($dir)
Expand Down Expand Up @@ -132,16 +138,15 @@ private static function deleteDirectory($dir)

public static function registerPlugin($pluginName)
{
$pluginName = __NAMESPACE__ . '\\' . $pluginName . "Plugin\\Load";
$pluginName = stripslashes(strtolower($pluginName));
self::$config['plugins'][$pluginName] = [];
self::$config['activated_plugins'][$pluginName] = true;
self::saveConfig();
}

public static function unregisterPlugin($pluginName)
{
// remove plugin from config file
$pluginName = __NAMESPACE__ . '\\' . $pluginName . "Plugin\\Load";
$pluginName = stripslashes(strtolower($pluginName));
unset(self::$config['plugins'][$pluginName]);
unset(self::$config['activated_plugins'][$pluginName]);
self::saveConfig();
Expand Down Expand Up @@ -228,4 +233,4 @@ private static function saveConfig($config = null)
$config = $config ?? self::$config;
file_put_contents(self::$configFile, json_encode($config, JSON_PRETTY_PRINT));
}
}
}
39 changes: 16 additions & 23 deletions src/lifeCycle.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,37 @@

namespace Bethropolis\PluginSystem;


use Bethropolis\PluginSystem\System;
use Bethropolis\PluginSystem\Info;

class LifeCycle
{
private $pluginDir;
private $info;

public function __construct()
{
$this->pluginDir = System::getPluginsDir();
$this->info = new Info();
}

public function onInstallation($pluginName)
{
$pluginConfigFile = $this->getPluginConfigPath($pluginName);

if (file_exists($pluginConfigFile)) {
$pluginConfig = json_decode(file_get_contents($pluginConfigFile), true);

if (isset($pluginConfig['files'])) {
foreach ($pluginConfig['files'] as $file) {
if (isset($file['target']) && isset($file['require'])) {
$targetFile = $this->resolveAbsolutePath(__DIR__ . '/' . $file['target']);
$requireFile = $this->resolveRelativePath($file['require'], $this->getPluginPath($pluginName));
if (file_exists($targetFile) && file_exists($requireFile)) {
// Append the require statement to the target file
$this->appendRequireStatement($targetFile, $requireFile);
}
}
}
}
}
$this->processPluginFiles($pluginName, 'append');
}

public function onUninstallation($pluginName)
{
$this->processPluginFiles($pluginName, 'remove');
}

private function processPluginFiles($pluginName, $action)
{
$pluginConfigFile = $this->getPluginConfigPath($pluginName);

if (file_exists($pluginConfigFile)) {
$pluginConfig = json_decode(file_get_contents($pluginConfigFile), true);
$this->info->addPlugin($pluginName, $pluginConfig);

if (isset($pluginConfig['files'])) {
foreach ($pluginConfig['files'] as $file) {
Expand All @@ -50,8 +41,8 @@ public function onUninstallation($pluginName)
$requireFile = $this->resolveRelativePath($file['require'], $this->getPluginPath($pluginName));

if (file_exists($targetFile) && file_exists($requireFile)) {
// Remove the appended require statement from the target file
$this->removeRequireStatement($targetFile, $requireFile);
// Perform the specified action (append or remove) on the target file
$this->$action($targetFile, $requireFile, $pluginName);
}
}
}
Expand All @@ -69,20 +60,22 @@ private function getPluginPath($pluginName)
return $this->pluginDir . $pluginName;
}

private function appendRequireStatement($targetFile, $requireFile)
private function append($targetFile, $requireFile, $pluginName)
{
$content = file_get_contents($targetFile);
$requireStatement = 'require "' . str_replace('\\', '/', $requireFile) . '";';


// Append the require statement to the target file if it doesn't exist already
if (strpos($content, $requireStatement) === false) {
$content .= PHP_EOL . $requireStatement . PHP_EOL;
file_put_contents($targetFile, $content);
}
}

private function removeRequireStatement($targetFile, $requireFile)
private function remove($targetFile, $requireFile, $pluginName)
{
$this->info->removePlugin($pluginName);
$content = file_get_contents($targetFile);
$requireStatement = 'require "' . str_replace('\\', '/', $requireFile) . '";';

Expand Down