flarum / framework

Simple forum software for building great communities.
http://flarum.org/
6.3k stars 835 forks source link

New PHP Extension API #851

Closed tobyzerner closed 6 years ago

tobyzerner commented 8 years ago

In every extension, we have an AddClientAssets listener which is basically the same:

class AddClientAssets
{
    public function subscribe(Dispatcher $events)
    {
        $events->listen(ConfigureClientView::class, [$this, 'addAssets']);
    }

    public function addAssets(ConfigureClientView $event)
    {
        if ($event->isForum()) {
            $event->addAssets([
                __DIR__.'/../../js/forum/dist/extension.js',
                __DIR__.'/../../less/forum/extension.less'
            ]);
            $event->addBootstrapper('flarum/auth/facebook/main');
        }

        if ($event->isAdmin()) {
            $event->addAssets([
                __DIR__.'/../../js/admin/dist/extension.js',
                __DIR__.'/../../less/forum/extension.less'
            ]);
            $event->addBootstrapper('flarum/auth/facebook/main');
        }
    }
}

Given that this asset file-structure is a best practice, we could reduce this duplication by providing an instantiable AddDefaultClientAssets listener. In bootstrap.php, instead of:

return function (Dispatcher $events) {
    $events->subscribe(Listener\AddClientAssets::class);
};

you would use:

return function (Dispatcher $events, Extension $extension) {
    $events->subscribe(new AddDefaultClientAssets($extension));
};

This would add the default asset file paths if they exist, along with JS bootstrappers using the Extension's ID as a prefix.

We could also extend this idea of shortcut listeners to other things, e.g.:

return function (Dispatcher $events) {
    $events->subscribe(new AddForumRoute($extension, 'get', '/auth/facebook', 'auth', FacebookAuthController::class));

    $events->subscribe(new AddPostType(DiscussionStickiedPost::class));
};

This needs discussion because to me it's a little unclear how far we would want to go with providing these helpers. Where do we draw the line?

tobyzerner commented 6 years ago

I think we should maintain the status quo (new Extend\Frontend) for the most common use-case which is extending an existing frontend. Every extension developer will have to do this, while most will never have to even think about creating a new frontend.

To create a new frontend, I like the static method as suggested by @franzliedke. Since the inheritance is optional, we could make it a new method? Perhaps:

return [
    (new Extend\Frontend('forum')) // extend an existing frontend
        ->css('file'),

    Extend\Frontend::create('embed') // create a new frontend
        ->inherit('forum')
        ->css('file')
];

Hmm actually, I don't even know if the static method is necessary...

behave differently depending on whether the frontend identified by $name exists or not is a rather confusing API.

It wouldn't really would it? All it would do is setup a binding in the container if one doesn't already exist.

tobyzerner commented 6 years ago

Actually - not even that is going to work. If an extension gets installed after Flarum has been installed, all of its migrations will be run. So extension migrations need to be kept up-to-date to work with the current core schema at all times, and then run after core migrations. Therefore, the addPermissions helper shouldn't cause any problems when used by extensions. Does that make sense?

franzliedke commented 6 years ago

Your last comment refers to https://github.com/flarum/core/pull/1344#discussion_r212527432, right?

sanjucta commented 6 years ago

Hi ,

Leaving this comment here as advised by Franz in this issue

It seems that in beta7 we can't use ConfigureForumRoutes to overwrite and existing route. I was trying to do something like

public function reRouteLogin(ConfigureForumRoutes $event) { $event->post('/login', 'login', Controllers\MyLogInController::class); }

That results in an exception - FastRoute\BadRouteException: Cannot register two routes matching "/login" for method "POST" in C:\wamp64\www\flarum\vendor\nikic\fast-route\src\DataGenerator\RegexBasedAbstract.php on line 55

franzliedke commented 6 years ago

Closing this, as the main infrastructure and quite a few extenders are already in place. I will create separate issues for the remaining extenders and assign them: