forked from GNUsocial/gnu-social
[CORE][EXTENSIONS] Added extension (modules, plugins) loading and test plugin, which is able to handle events
This commit is contained in:
parent
2f5bdeed62
commit
d8d2ad3e10
2
.gitignore
vendored
2
.gitignore
vendored
@ -19,3 +19,5 @@
|
||||
!.php_cs
|
||||
/.php_cs.cache
|
||||
###< friendsofphp/php-cs-fixer ###
|
||||
|
||||
plugins/available
|
@ -7,6 +7,7 @@
|
||||
"php": "^7.4",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"lstrojny/functional-php": "^1.11",
|
||||
"sensio/framework-extra-bundle": "^5.1",
|
||||
"symfony/asset": "5.0.*",
|
||||
"symfony/console": "5.0.*",
|
||||
@ -47,7 +48,8 @@
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/"
|
||||
"App\\": "src/",
|
||||
"Plugin\\": "plugins/enabled/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
|
144
composer.lock
generated
144
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "29d2cd792b5bb1a62925c27414e0a448",
|
||||
"content-hash": "0c92d597e3a31937bac9663d686a42eb",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@ -1428,6 +1428,148 @@
|
||||
],
|
||||
"time": "2020-01-07T22:58:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "lstrojny/functional-php",
|
||||
"version": "1.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lstrojny/functional-php.git",
|
||||
"reference": "df0e516eb44cd0579eeaff57023ef41ffa11947f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/lstrojny/functional-php/zipball/df0e516eb44cd0579eeaff57023ef41ffa11947f",
|
||||
"reference": "df0e516eb44cd0579eeaff57023ef41ffa11947f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~7"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.14",
|
||||
"phpunit/phpunit": "~7",
|
||||
"squizlabs/php_codesniffer": "~3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Functional\\": "src/Functional"
|
||||
},
|
||||
"files": [
|
||||
"src/Functional/Average.php",
|
||||
"src/Functional/ButLast.php",
|
||||
"src/Functional/Capture.php",
|
||||
"src/Functional/ConstFunction.php",
|
||||
"src/Functional/CompareOn.php",
|
||||
"src/Functional/CompareObjectHashOn.php",
|
||||
"src/Functional/Compose.php",
|
||||
"src/Functional/Concat.php",
|
||||
"src/Functional/Contains.php",
|
||||
"src/Functional/Converge.php",
|
||||
"src/Functional/Curry.php",
|
||||
"src/Functional/CurryN.php",
|
||||
"src/Functional/Difference.php",
|
||||
"src/Functional/DropFirst.php",
|
||||
"src/Functional/DropLast.php",
|
||||
"src/Functional/Each.php",
|
||||
"src/Functional/Equal.php",
|
||||
"src/Functional/ErrorToException.php",
|
||||
"src/Functional/Every.php",
|
||||
"src/Functional/False.php",
|
||||
"src/Functional/Falsy.php",
|
||||
"src/Functional/Filter.php",
|
||||
"src/Functional/First.php",
|
||||
"src/Functional/FirstIndexOf.php",
|
||||
"src/Functional/FlatMap.php",
|
||||
"src/Functional/Flatten.php",
|
||||
"src/Functional/Flip.php",
|
||||
"src/Functional/GreaterThan.php",
|
||||
"src/Functional/GreaterThanOrEqual.php",
|
||||
"src/Functional/Group.php",
|
||||
"src/Functional/Head.php",
|
||||
"src/Functional/Id.php",
|
||||
"src/Functional/IfElse.php",
|
||||
"src/Functional/Identical.php",
|
||||
"src/Functional/IndexesOf.php",
|
||||
"src/Functional/Intersperse.php",
|
||||
"src/Functional/Invoke.php",
|
||||
"src/Functional/InvokeFirst.php",
|
||||
"src/Functional/InvokeIf.php",
|
||||
"src/Functional/InvokeLast.php",
|
||||
"src/Functional/Invoker.php",
|
||||
"src/Functional/Last.php",
|
||||
"src/Functional/LastIndexOf.php",
|
||||
"src/Functional/LessThan.php",
|
||||
"src/Functional/LessThanOrEqual.php",
|
||||
"src/Functional/LexicographicCompare.php",
|
||||
"src/Functional/Map.php",
|
||||
"src/Functional/Match.php",
|
||||
"src/Functional/Maximum.php",
|
||||
"src/Functional/Memoize.php",
|
||||
"src/Functional/Minimum.php",
|
||||
"src/Functional/None.php",
|
||||
"src/Functional/Noop.php",
|
||||
"src/Functional/Not.php",
|
||||
"src/Functional/OmitKeys.php",
|
||||
"src/Functional/PartialAny.php",
|
||||
"src/Functional/PartialLeft.php",
|
||||
"src/Functional/PartialMethod.php",
|
||||
"src/Functional/PartialRight.php",
|
||||
"src/Functional/Partition.php",
|
||||
"src/Functional/Pick.php",
|
||||
"src/Functional/Pluck.php",
|
||||
"src/Functional/Poll.php",
|
||||
"src/Functional/Product.php",
|
||||
"src/Functional/Ratio.php",
|
||||
"src/Functional/ReduceLeft.php",
|
||||
"src/Functional/ReduceRight.php",
|
||||
"src/Functional/Reindex.php",
|
||||
"src/Functional/Reject.php",
|
||||
"src/Functional/Repeat.php",
|
||||
"src/Functional/Retry.php",
|
||||
"src/Functional/Select.php",
|
||||
"src/Functional/SelectKeys.php",
|
||||
"src/Functional/SequenceConstant.php",
|
||||
"src/Functional/SequenceExponential.php",
|
||||
"src/Functional/SequenceLinear.php",
|
||||
"src/Functional/Some.php",
|
||||
"src/Functional/Sort.php",
|
||||
"src/Functional/Sum.php",
|
||||
"src/Functional/SuppressError.php",
|
||||
"src/Functional/Tap.php",
|
||||
"src/Functional/Tail.php",
|
||||
"src/Functional/TailRecursion.php",
|
||||
"src/Functional/TakeLeft.php",
|
||||
"src/Functional/TakeRight.php",
|
||||
"src/Functional/True.php",
|
||||
"src/Functional/Truthy.php",
|
||||
"src/Functional/Unique.php",
|
||||
"src/Functional/With.php",
|
||||
"src/Functional/Zip.php",
|
||||
"src/Functional/ZipAll.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Lars Strojny",
|
||||
"email": "lstrojny@php.net",
|
||||
"homepage": "http://usrportage.de"
|
||||
},
|
||||
{
|
||||
"name": "Max Beutel",
|
||||
"email": "nash12@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Functional primitives for PHP",
|
||||
"keywords": [
|
||||
"functional"
|
||||
],
|
||||
"time": "2019-12-19T16:01:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "2.0.2",
|
||||
|
11
plugins/available/Test/Test.php
Normal file
11
plugins/available/Test/Test.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Plugin\Test;
|
||||
|
||||
class Test
|
||||
{
|
||||
public function onTest(string $foo)
|
||||
{
|
||||
dump('Event handled: ' . $foo);
|
||||
}
|
||||
}
|
1
plugins/enabled/Test
Symbolic link
1
plugins/enabled/Test
Symbolic link
@ -0,0 +1 @@
|
||||
../available/Test/
|
@ -2,15 +2,15 @@
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Util\GSEvent;
|
||||
|
||||
use App\Util\GSEvent as Event;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
|
||||
class NetworkPublic extends AbstractController
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
GSEvent::handle('test', ['foobar']);
|
||||
Event::handle('Test', ['foobar']);
|
||||
|
||||
return $this->render('network/public.html.twig', []);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,34 @@ class Kernel extends BaseKernel
|
||||
|
||||
private const CONFIG_EXTS = '.{php,xml,yaml,yml}';
|
||||
|
||||
public function __construct(string $environment, bool $debug)
|
||||
{
|
||||
parent::__construct($environment, $debug);
|
||||
|
||||
if (!\defined('INSTALLDIR')) {
|
||||
define('INSTALLDIR', dirname(__DIR__));
|
||||
define('SRCDIR', INSTALLDIR . '/src');
|
||||
define('PUBLICDIR', INSTALLDIR . '/public');
|
||||
define('GNUSOCIAL_ENGINE', 'GNU social');
|
||||
// MERGE Change to https://gnu.io/social/
|
||||
define('GNUSOCIAL_ENGINE_URL', 'https://gnusocial.network/');
|
||||
// MERGE Change to https://git.gnu.io/gnu/gnu-social
|
||||
define('GNUSOCIAL_ENGINE_REPO_URL', 'https://notabug.org/diogo/gnu-social/');
|
||||
// Current base version, major.minor.patch
|
||||
define('GNUSOCIAL_BASE_VERSION', '3.0.0');
|
||||
// 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
|
||||
define('GNUSOCIAL_LIFECYCLE', 'dev');
|
||||
define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
|
||||
define('GNUSOCIAL_CODENAME', 'Big bang');
|
||||
|
||||
// Work internally in UTC
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
// Work internally with UTF-8
|
||||
mb_internal_encoding('UTF-8');
|
||||
}
|
||||
}
|
||||
|
||||
public function registerBundles(): iterable
|
||||
{
|
||||
$contents = require $this->getProjectDir() . '/config/bundles.php';
|
||||
@ -37,6 +65,7 @@ class Kernel extends BaseKernel
|
||||
$container->addResource(new FileResource($this->getProjectDir() . '/config/bundles.php'));
|
||||
$container->setParameter('container.dumper.inline_class_loader', PHP_VERSION_ID < 70400 || $this->debug);
|
||||
$container->setParameter('container.dumper.inline_factories', true);
|
||||
|
||||
$confDir = $this->getProjectDir() . '/config';
|
||||
|
||||
$loader->load($confDir . '/{packages}/*' . self::CONFIG_EXTS, 'glob');
|
||||
|
@ -17,6 +17,9 @@
|
||||
|
||||
namespace App\Util;
|
||||
|
||||
use Functional as F;
|
||||
use Symfony\Component\Config\Definition\Exception\Exception;
|
||||
|
||||
abstract class Common
|
||||
{
|
||||
public static function config(string $section, string $field)
|
||||
@ -44,10 +47,40 @@ abstract class Common
|
||||
} else {
|
||||
// We might be running directly from the plugins dir?
|
||||
// If so, there's no place to store locale info.
|
||||
Log::error('The GNU social install dir seems to contain a piece named plugin');
|
||||
return false;
|
||||
throw new Exception('The GNU social install dir seems to contain a piece named plugin');
|
||||
}
|
||||
|
||||
return $final;
|
||||
}
|
||||
|
||||
public static function swapArgs($call, $arg)
|
||||
{
|
||||
return function ($v) use ($call, $arg) { return self::$call($v, $arg); };
|
||||
}
|
||||
|
||||
public static function startsWith($haystack, string $needle): bool
|
||||
{
|
||||
if (is_string($haystack)) {
|
||||
$length = strlen($needle);
|
||||
return substr($haystack, 0, $length) === $needle;
|
||||
}
|
||||
return F\every($haystack,
|
||||
function ($haystack) use ($needle) {
|
||||
return self::startsWith($haystack, $needle);
|
||||
});
|
||||
}
|
||||
|
||||
public static function endsWith($haystack, string $needle)
|
||||
{
|
||||
if (is_string($haystack)) {
|
||||
$length = strlen($needle);
|
||||
if ($length == 0) {
|
||||
return true;
|
||||
}
|
||||
return substr($haystack, -$length) === $needle;
|
||||
}
|
||||
return F\every($haystack,
|
||||
function ($haystack) use ($needle) {
|
||||
return self::endsWith($haystack, $needle);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
33
src/Util/ExtensionManager.php
Normal file
33
src/Util/ExtensionManager.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Util;
|
||||
|
||||
use App\Util\GSEvent as Event;
|
||||
use Functional as F;
|
||||
|
||||
abstract class ExtensionManager
|
||||
{
|
||||
public static array $extensions = [];
|
||||
|
||||
public static function loadExtensions()
|
||||
{
|
||||
$plugins_paths = glob(INSTALLDIR . '/plugins/enabled/*');
|
||||
|
||||
foreach ($plugins_paths as $plugin_path) {
|
||||
$class_name = basename($plugin_path);
|
||||
$qualified = 'Plugin\\' . $class_name . '\\' . $class_name;
|
||||
|
||||
require_once $plugin_path . '/' . $class_name . '.php';
|
||||
$class = new $qualified;
|
||||
self::$extensions[] = $class;
|
||||
|
||||
// Register event handlers
|
||||
$methods = get_class_methods($class);
|
||||
$events = F\select($methods, Common::swapArgs('startsWith', 'on'));
|
||||
F\map($events,
|
||||
function (string $m) use ($class) {
|
||||
Event::addHandler(substr($m, 2), [$class, $m]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -63,9 +63,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
class GNUsocial implements EventSubscriberInterface
|
||||
{
|
||||
protected ContainerInterface $container;
|
||||
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
protected TranslatorInterface $translator;
|
||||
|
||||
public function __construct(ContainerInterface $container,
|
||||
@ -75,40 +73,17 @@ class GNUsocial implements EventSubscriberInterface
|
||||
$this->container = $container;
|
||||
$this->logger = $logger;
|
||||
$this->translator = $translator;
|
||||
|
||||
if (!\defined('INSTALLDIR')) {
|
||||
define('INSTALLDIR', dirname(__DIR__));
|
||||
define('SRCDIR', INSTALLDIR . '/src');
|
||||
define('PUBLICDIR', INSTALLDIR . '/public');
|
||||
define('GNUSOCIAL_ENGINE', 'GNU social');
|
||||
// MERGE Change to https://gnu.io/social/
|
||||
define('GNUSOCIAL_ENGINE_URL', 'https://gnusocial.network/');
|
||||
// MERGE Change to https://git.gnu.io/gnu/gnu-social
|
||||
define('GNUSOCIAL_ENGINE_REPO_URL', 'https://notabug.org/diogo/gnu-social/');
|
||||
// Current base version, major.minor.patch
|
||||
define('GNUSOCIAL_BASE_VERSION', '3.0.0');
|
||||
// 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
|
||||
define('GNUSOCIAL_LIFECYCLE', 'dev');
|
||||
define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
|
||||
define('GNUSOCIAL_CODENAME', 'Big bang');
|
||||
|
||||
// Work internally in UTC
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
// Work internally with UTF-8
|
||||
mb_internal_encoding('UTF-8');
|
||||
}
|
||||
}
|
||||
|
||||
public function onKernelRequest(RequestEvent $event,
|
||||
string $event_name,
|
||||
$event_dispatcher): RequestEvent
|
||||
{
|
||||
if (!\defined('INSTALLDIR')) {
|
||||
Log::setLogger($this->logger);
|
||||
GSEvent::setDispatcher($event_dispatcher);
|
||||
I18n::setTranslator($this->translator);
|
||||
}
|
||||
Log::setLogger($this->logger);
|
||||
GSEvent::setDispatcher($event_dispatcher);
|
||||
I18n::setTranslator($this->translator);
|
||||
ExtensionManager::loadExtensions();
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
|
@ -66,10 +66,11 @@ abstract class GSEvent
|
||||
self::$dispatcher->addListener(
|
||||
$name,
|
||||
function ($event, $event_name, $dispatcher) use ($handler) {
|
||||
if ($event instanceof GenericEvent
|
||||
// Old style of events (preferred)
|
||||
&& call_user_func_array($handler, $event->getArguments()) == self::stop) {
|
||||
$event->stopPropagation();
|
||||
// Old style of events (preferred)
|
||||
if ($event instanceof GenericEvent) {
|
||||
if (call_user_func_array($handler, $event->getArguments()) == self::stop) {
|
||||
$event->stopPropagation();
|
||||
}
|
||||
return $event;
|
||||
}
|
||||
// Symfony style of events
|
||||
|
@ -120,6 +120,9 @@
|
||||
"laminas/laminas-zendframework-bridge": {
|
||||
"version": "1.0.1"
|
||||
},
|
||||
"lstrojny/functional-php": {
|
||||
"version": "1.11.0"
|
||||
},
|
||||
"monolog/monolog": {
|
||||
"version": "2.0.2"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user