Added: support plugins als .phar files

This commit is contained in:
djmaze 2021-03-04 11:56:26 +01:00
parent 46ff83c41d
commit 1e13725768
4 changed files with 77 additions and 22 deletions

View file

@ -29,21 +29,42 @@ class ChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
protected function getSupportedDrivers(bool $all = false) : iterable protected function getSupportedDrivers(bool $all = false) : iterable
{ {
// foreach (\glob(__DIR__ . '/../change-password-*', GLOB_ONLYDIR) as $file) { if ($phar_file = \Phar::running()) {
foreach (\glob(__DIR__ . '/drivers/*.php') as $file) { $phar = new \Phar($phar_file, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME);
try foreach (new \RecursiveIteratorIterator($phar) as $file) {
{ if (\preg_match('#/drivers/([a-z]+)\\.php$#Di', $file, $m)) {
$name = \basename($file, '.php'); try
if ($all || $this->Config()->Get('plugin', "driver_{$name}_enabled", false)) { {
require_once $file; if ($all || $this->Config()->Get('plugin', "driver_{$m[1]}_enabled", false)) {
$class = 'ChangePasswordDriver' . $name; require_once $file;
if ($class::isSupported()) { $class = 'ChangePasswordDriver' . $m[1];
yield $name => $class; if ($class::isSupported()) {
yield $m[1] => $class;
}
}
}
catch (\Throwable $oException)
{
} }
} }
} }
catch (\Throwable $oException) } else {
{ // foreach (\glob(__DIR__ . '/../change-password-*', GLOB_ONLYDIR) as $file) {
foreach (\glob(__DIR__ . '/drivers/*.php') as $file) {
try
{
$name = \basename($file, '.php');
if ($all || $this->Config()->Get('plugin', "driver_{$name}_enabled", false)) {
require_once $file;
$class = 'ChangePasswordDriver' . $name;
if ($class::isSupported()) {
yield $name => $class;
}
}
}
catch (\Throwable $oException)
{
}
} }
} }
} }

View file

@ -52,6 +52,15 @@ if (isset($options['plugins'])) {
$tar->compress(Phar::GZ); $tar->compress(Phar::GZ);
unlink($tar_destination); unlink($tar_destination);
rename("{$tar_destination}.gz", $tgz_destination); rename("{$tar_destination}.gz", $tgz_destination);
if (Phar::canWrite()) {
$phar_destination = "{$destPath}{$name}.phar";
@unlink($phar_destination);
$tar = new Phar($phar_destination);
$tar->buildFromDirectory("./plugins/{$name}/");
$tar->compress(Phar::GZ);
unlink($phar_destination);
rename("{$phar_destination}.gz", $phar_destination);
}
} else { } else {
echo "- {$name} {$version}\n"; echo "- {$name} {$version}\n";
} }

View file

@ -694,7 +694,9 @@ trait Admin
private static function deletePackageDir(string $sId) : bool private static function deletePackageDir(string $sId) : bool
{ {
return !\is_dir(APP_PLUGINS_PATH.$sId) || \MailSo\Base\Utils::RecRmDir(APP_PLUGINS_PATH.$sId); $sPath = APP_PLUGINS_PATH.$sId;
return (!\is_dir($sPath) || \MailSo\Base\Utils::RecRmDir($sPath))
&& (!\is_file("{$sPath}.phar") || \unlink("{$sPath}.phar"));
} }
private function downloadRemotePackageByUrl(string $sUrl) : string private function downloadRemotePackageByUrl(string $sUrl) : string
@ -762,8 +764,12 @@ trait Admin
if ($sTmp) if ($sTmp)
{ {
$oArchive = new \PharData($sTmp, 0, $sRealFile); $oArchive = new \PharData($sTmp, 0, $sRealFile);
if (!\is_dir(APP_PLUGINS_PATH.$sId) || static::deletePackageDir($sId)) { if (static::deletePackageDir($sId)) {
$bResult = $oArchive->extractTo(APP_PLUGINS_PATH); if ('.phar' === \substr($sRealFile, -5)) {
$bResult = \copy($sTmp, APP_PLUGINS_PATH . \basename($sRealFile));
} else {
$bResult = $oArchive->extractTo(APP_PLUGINS_PATH);
}
if (!$bResult) { if (!$bResult) {
$this->Logger()->Write('Cannot extract package files: '.$oArchive->getStatusString(), \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER'); $this->Logger()->Write('Cannot extract package files: '.$oArchive->getStatusString(), \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
} }

View file

@ -108,6 +108,18 @@ class Manager
} }
} }
protected static function getPluginPath(string $sName) : ?string
{
$sPath = APP_PLUGINS_PATH.$sName;
if (\is_readable("{$sPath}/index.php")) {
return $sPath;
}
if (\is_readable("{$sPath}.phar")) {
return "phar://{$sPath}.phar";
}
return null;
}
public function CreatePluginByName(string $sName) : ?\RainLoop\Plugins\AbstractPlugin public function CreatePluginByName(string $sName) : ?\RainLoop\Plugins\AbstractPlugin
{ {
$oPlugin = null; $oPlugin = null;
@ -117,7 +129,7 @@ class Manager
$oPlugin = new $sClassName(); $oPlugin = new $sClassName();
$oPlugin $oPlugin
->SetName($sName) ->SetName($sName)
->SetPath(APP_PLUGINS_PATH.$sName) ->SetPath(static::getPluginPath($sName))
->SetPluginManager($this) ->SetPluginManager($this)
->SetPluginConfig(new \RainLoop\Config\Plugin($sName, $oPlugin->ConfigMap())) ->SetPluginConfig(new \RainLoop\Config\Plugin($sName, $oPlugin->ConfigMap()))
; ;
@ -130,12 +142,18 @@ class Manager
{ {
$aList = array(); $aList = array();
$aGlob = \glob(APP_PLUGINS_PATH.'*', GLOB_ONLYDIR|GLOB_NOSORT); $aGlob = \glob(APP_PLUGINS_PATH.'*');
if (\is_array($aGlob)) if (\is_array($aGlob))
{ {
foreach ($aGlob as $sPathName) foreach ($aGlob as $sPathName)
{ {
$sName = \basename($sPathName); if (\is_dir($sPathName)) {
$sName = \basename($sPathName);
} else if ('.phar' === \substr($sPathName, -5)) {
$sName = \basename($sPathName, '.phar');
} else {
continue;
}
$sClassName = $this->loadPluginByName($sName); $sClassName = $this->loadPluginByName($sName);
if ($sClassName) { if ($sClassName) {
$aList[] = array( $aList[] = array(
@ -164,12 +182,13 @@ class Manager
public function loadPluginByName(string $sName) : ?string public function loadPluginByName(string $sName) : ?string
{ {
if (\preg_match('/^[a-z0-9\-]+$/', $sName) if (\preg_match('/^[a-z0-9\\-]+$/', $sName)) {
&& \is_readable(APP_PLUGINS_PATH.$sName.'/index.php'))
{
$sClassName = $this->convertPluginFolderNameToClassName($sName); $sClassName = $this->convertPluginFolderNameToClassName($sName);
if (!\class_exists($sClassName)) { if (!\class_exists($sClassName)) {
include_once APP_PLUGINS_PATH.$sName.'/index.php'; $sPath = static::getPluginPath($sName);
if (\is_readable($sPath.'/index.php')) {
include_once $sPath.'/index.php';
}
} }
if (\class_exists($sClassName) && \is_subclass_of($sClassName, 'RainLoop\\Plugins\\AbstractPlugin')) { if (\class_exists($sClassName) && \is_subclass_of($sClassName, 'RainLoop\\Plugins\\AbstractPlugin')) {
return $sClassName; return $sClassName;