PrestaShop / prestafony-project

Some resources to help you migrate PrestaShop to Symfony 3
https://github.com/PrestaShop/prestafony-project/projects/1
11 stars 8 forks source link

Allow modules to create symfony controllers #30

Closed sarjon closed 6 years ago

sarjon commented 6 years ago

Symfony is here, so why not allow module developers to make use of it and introduce symfony controllers for modules? I've been playing around with PrestaShop modules and i came up with this. Maybe it will give some ideas for future development. :)

First some changes to core

Create custom routes loader for modules and register it

I've implmented PrestaShopBundle\Routing\ModuleRouteLoader which load() methods looks like this, but could be improved by loading only installed modules.

// src/PrestaShopBundle/Routing/ModuleRouteLoader.php

public function load($resource, $type = null)
{
    $routes = new RouteCollection();

    $moduleDirs = Finder::create()
        ->directories()
        ->in(__DIR__.'/../../../modules')
        ->depth('0');

    foreach ($moduleDirs as $modulePath) {
        if (file_exists($modulePath.'/config/routes.yml')) {
            $loadedRoutes = $this->import(
                $modulePath.'/config/routes.yml',
                'yaml'
            );

            $routes->addCollection($loadedRoutes);
        }
    }

    return $routes;
}

Register routes loader:

# src/PrestaShopBundle/Resources/config/services/bundle/routing.yml
prestashop.bundle.routing.module_route_loader:
    class: 'PrestaShopBundle\Routing\ModuleRouteLoader'
    tags: [routing.loader]

Finally, add new entry point for module routes:

# app/config/routing.yml
app_modules:
    resource: .
    type: module
    prefix: /modules

Configure new path entry for twig templates so module templates can be rendered

# app/config/config.yml
twig:
    paths:
        ...
        # Add additional path
        '%kernel.root_dir%/../modules': Modules

Thats it for core changes.

A demo module

Here's how module directory structure looks like: ademo

Routes file in module:

# modules/ademo/config/routes.yml
ademo_admin_demo:
    path: ademo/demo
    methods: [GET]
    defaults:
      _controller: 'Sarjon\Ademo\Controller\Admin\DemoController::demoAction'

Module template file:

{# modules/ademo/templates/admin/demo.html.twig #}
{% extends '@PrestaShop/Admin/layout.html.twig' %}

{% block content %}
  <h1>Module controller made with Symfony!</h1>
{% endblock %}

And finally a controller:

// modules/ademo/src/Controller/Admin/DemoController.php
namespace Sarjon\Ademo\Admin\Controller;

use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;

class DemoController extends FrameworkBundleAdminController
{
    public function demoAction()
    {
        return $this->render('@Modules/ademo/templates/admin/demo.html.twig');
    }
}

Now access http://prestashop.local/admin-dev/index.php/modules/ademo/demo and here we have page rendered with module using symfony controller! ademo_page

sarjon commented 6 years ago

ping @mickaelandrieu

mickaelandrieu commented 6 years ago

I've already done it => it's amazing how similar are our ideas, you're like a copy of me, but younger and with more muscles xD

Edit: can I adapt your suggestion ? I think adding a module loader can be a good addition too :)

/c @Quetzacoalt91

mickaelandrieu commented 6 years ago

@sarjon this is the tree of my poc module

my_poc_module

Did you have installed a bot to steal my work on my computer? xD

sarjon commented 6 years ago

nice! :smile:

it would also be great if module controllers could use both annotations & yml for defining routes. :)

mickaelandrieu commented 6 years ago

You don't even let me time to play LoL, I'll finish my PR right now.

It's really funny ^^ /c @toutantic

sarjon commented 6 years ago

I'll finish my PR right now.

i cant wait for this feature to be available in core. :)

mickaelandrieu commented 6 years ago

@sarjon I've ended up improving your proposal instead of working on annotations :trollface:

I have found a weird issue with annotations, and I need more time to work on supporting them in this context)

mickaelandrieu commented 6 years ago

The support of annotations is not a blocking issue and can be introduced later => closed!

Thanks for your contribution @sarjon :)

mickaelandrieu commented 6 years ago

@toutantic support of "modern/Symfony" controllers is now merged in develop branch and will be shipped in 1.7.5.