Type: tech-issue
mmhhm, what else can you tell us about this? ^^
No more seriously, I thought we didn't want to use doctrine Entities and get rid of ObjectModel as well, and rather use CQRS pattern to update the database and avoid being too attached to a static object representation?
But maybe I got something wrong
It's because I did not write a proper description 😅 (I meant to but I switched half-way to another topic and forgot to finish it).
If I'm not wrong, the feature required by @eternoendless and @mickaelandrieu is "Modules should be able to describe and manage dedicated SQL tables for their needs."
So Doctrine here would be used to add entities to the project, not modify/manage existing ones. To modify/manage existing ones the goal is indeed to use CQRS commands.
Ok, and will this be used if someone wants to "extend" our model?
You would attach a CustomProduct
entity to a Product
row?
I'm afraid we are going to mix several ways of managing the database together. Like a query which uses half a doctrine builder in CQRS mode for the core tables, mixed with entities for the module tables..
The idea is to let module developers handle _their_ data as they see fit. Doctrine is a good answer.
The idea is _NOT_ to let them extend PrestaShop's tables. We must discourage that as much as possible. Of course, a custom shop should be able to customize stuff as much as they need, but using our pre-defined paths as much as possible.
Great !!!
Be able to use doctrine-migrations along with this could be also a good idea, no ?
In the current version (1.7.5.0) what's prevent to use Doctrine entities in module ?
@psyray Doctrine currently only looks in PrestaShopBundle
directory for entities. It ignores modules
directory.
This is the only blocking item I see 🤔 then we need also to check what it means: where can we declare repositories, how to deal with migrations ...
Also there is a debate whether we will enable Doctrine DBAL and/or Doctrine ORM (ping @mickaelandrieu ) as Doctrine can add complexity to the project so maybe it's too much ...
OK thanks.
With namespace I can join the entity dir in my module, no ?
This module mainly interacts with the Product (which was already migrated to Symfony)
The only problem is that I have to access the good old ObjectModel.
Do you have a documentation to use the CQRS part in Prestashop ? (other than looking into the code)
I'm currently developing a module for a customer, and I'm using the modern controller way ;)
I just want to use the future good technology based on Symfony & Doctrine...
My module does not need to be compatible with version under 1.7.5.0.
So, could I accomplish this and is there any workflow of the current state ?
I know that Prestashop is currently "le cul entre 2 chaises", I just want to make things good and be compliant with future Prestashop module usage.
Do you have a documentation to use the CQRS part in Prestashop ? (other than looking into the code)
Not yet as we are still experimenting around CQRS : we have not fixed 100% "how CQRS is used in prestashop". Once we have explored all issues it creates (because adding something in a software project always creates issues 😄 ) and fixed them, we will write the doc.
I'm sorry right now we dont have this workflow. My advice would be to keep the good old ObjectModel behavior but wrap it inside a class/function in order to make it easy to replace it later with modern behavior.
I will follow your advice and wrap ObjectModel into a class.
Thanks for your reply.
Anyway Prestashop is on the good way, thanks too for your work :+1:
I managed to achieve my goals by adding my module doctrine mappings in the config.yml.
Here is the config :
orm
.....
mappings:
MyModule:
type: annotation
is_bundle: false
dir: %kernel.root_dir%/../modules/module_name/src/Entity
prefix: MyNamespace\Entity
alias: MyModule
It works, I can access my entities and using them with Doctrine entity manager.
So as @eternoendless said, I can "handle my datas as they see fit", and it's more flexible for me.
I could declare the ManyToOne/OneToMany/ManyToMany annotation for the existing Prestashop entities, like Shop, Shop Group...
To have doctrine migrations I've downloaded the composer.json from the github 1.7.5.x branch, and I've added the doctrine/doctrine-migrations-bundle:^1.3 with composer require, and add the following line in the app/AppKernel.php
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
It works well.
Of course, my goal is not to extend the Prestashop entities, but only manage my own entities with Doctrine, which is more flexible and powerful than the ObjectModel.
I will continue to use ObjectModel to get/insert/update Prestashop datas.
@matks According to your Prestashop knowledge, may I do something wrong ?
@psyray very nice work ! And thank you for sharing 😄
I could declare the ManyToOne/OneToMany/ManyToMany annotation for the existing Prestashop entities, like Shop, Shop Group...
Risky thing 1: since these models are handled by ObjectModel they might be updated and break the model consistency. Imagine if some module makes a nullable row that you have linked as a foreign key ...
Since you are on your shop you have the control so if you are rigorous, you should be fine 😉
Risky thing 2: you'll have 3 SQL migrations tools in use in your shop. The standard 1-click upgrade module which performs SQL migrations, whenever you install/upgrade a module it is able to perform SQL migrations too, and you added Doctrine Migrations.
Nothing wrong here, but you need to check what each of them do in order to keep them in sync 😉
How to use namespaces in custom module ? Using doctrine without using also ownnamespace and composer, should not be possible..
@Bonobomagno I think it's possible to use Doctrine without namespace but it's a complex configuration. So probably yes, you need namespace, and composer is the easiest solution to autoload namespaced php classes.
Is it an issue for you ? Is it a bad thing in your case that in order to use Doctrine, you need to autoload your module using composer and provide namespace for your classes ?
@psyray very nice work ! And thank you for sharing smile
Thanks
Risky thing 1: since these models are handled by ObjectModel they might be updated and break the model consistency. Imagine if some module makes a nullable row that you have linked as a foreign key ...
You're right.
It's a side effect, but as I use only main Prestashop table, like product or shop, I don't think the id_product or id_shop will change to null :)
Risky thing 2: you'll have 3 SQL migrations tools in use in your shop. The standard 1-click upgrade module which performs SQL migrations, whenever you install/upgrade a module it is able to perform SQL migrations too, and you added Doctrine Migrations.
Nothing wrong here, but you need to check what each of them do in order to keep them in sync wink
For updating model I will only use the update process of the module (update folder, with upgrade php file and SQL query)
I will use Doctrine migrations only to generate the SQL query to execute for an upgrade using the module upgrade.
I could easily track changes based on my entities modification, it's a one click process :)
And the 1-click upgrade wil not take care of my module.
@matks Thanks for your reply, now it's time to work ;)
I have no problem using composer, it is the main utility on laravel/symfony project ofc.
The main problem that i faced is that there is no standard way to use both prestashop and custom module namespaces. Most of modules dont use namespace for own files and actually this thing disturbs me.
So , how do you handle BOTH prestashop namespaces and modules one? Using a custom autoloader? or there are some fine customization for using composer INSIDE the module?
@Bonobomagno With the global namespace, you can access module classes
To achieve this, prefix with \ when calling the class, eg:
\Ps_banner::clearStaticCache()
$psBannerClass = new \Ps_banner()
With a good IDE (I use Eclipse PDT) and autocompletion, it's automatic ;)
So you are using local namespace with composer in your module and global one for access prestashop namespaces?
any issue about it?
Maybe with the views part?
Btw, this will multiply vendor dir in a prestashop installation , is this good? :/
You can access Prestashop defined namespace (which is already migrated to Symfony and located in the src folder) with
PrestashopBundle\[Controller,Entity...]\...
Prestashop\Prestashop\[Core,Adapter]\...
You can access your module namespace with MyModule\...
And you can access all others classes, which do not have a defined namespace (the legacy ones not already migrated), from the global namespacewith \Class
I don't have any issue yet. I think there should be no problem.
The vendor dir in your module only contains the composer autoload.php file which is included in the Prestashop environment at the app/AppKernel.php level
@Bonobomagno
So , how do you handle BOTH prestashop namespaces and modules one? Using a custom autoloader? or there are some fine customization for using composer INSIDE the module?
Unfortunately, for backwards compatibility the main module file must be in the root namespace. But this doesn't mean all of the modules' classes have to, you can use any namespace you'd like (example).
this will multiply vendor dir in a prestashop installation, is this good?
The vendor
directory will be created inside your own module. There's no issue about it, but you have to be extra careful about importing libraries with composer, as you may encounter collisions with PrestaShop's own libraries or other modules'.
This system will most likely change in the next major version so that modules are fully namespaced, distributed and installed using composer.
I'm a bit confused now, psyray say one thing, eternoendless an other..
i have to use namespace PrestaShop\Module\MyCustomModule
or namespace MyCustomModule
?
The first one is not cool, but the second one seems too nice to be true..
For the time being, it can be whatever you like. I think MyCustomModule
is a better fit. Remember that you will have to configure your namespace in your composer.json for autoloading to work.
A good namespace is Vendor\ModuleName
Example :
Given the module name is MyCustomModule and the vendor is Me.
So the namespace could be MeMyCustomModule
The module dir is my_custom_module and the module root php file is my_custom_module.php
Your code with the namespace is under the src folder in the my_custom_module root folder
Here a composer.json example.
{
"name": "me/my_custom_module",
"description": "Me - MyCustomModule",
"homepage": "https://www.mycustommodule.com",
"license": "AFL-3.0",
"version": "1.0",
"authors": [
{
"name": "You",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.6.0"
},
"autoload": {
"psr-4": {
"Me\\MyCustomModule\\": "src/"
},
"classmap": ["my_custom_module.php"],
"exclude-from-classmap": []
},
"config": {
"preferred-install": "dist"
},
"type": "prestashop-module"
}
You launch composer install
from the my_custom_module dir and the autoloader.php is generated under the vendor dir.
Et voilà , now Prestashop will load your module (if it has been activated) and you can use the power of Symfony and use modern controllers in Prestashop.
All the above stuff is explained in the Prestashop dev docs.
Take the time to read the dev docs.
Nice tip!
This docs are pretty new, didn't saw them before
Il giorno lun 7 gen 2019, 18:03 Psyray notifications@github.com ha
scritto:
A good namespace is Vendor\ModuleName
Example :
Given the module name is MyCustomModule and the vendor is Me.
So the namespace could be MeMyCustomModule
The module dir is my_custom_module and the module root php file is
my_custom_module.php
Your code with the namespace is under the src folder in the
my_custom_module root folderHere a composer.json example.
{
"name": "me/my_custom_module",
"description": "Me - MyCustomModule",
"homepage": "https://www.mycustommodule.com",
"license": "AFL-3.0",
"version": "1.0",
"authors": [
{ "name": "You", "email": "[email protected]" }
],
"require": {
"php": ">=5.6.0"
},
"autoload": {
"psr-4": { "Me\\MyCustomModule\\": "src/" }, "classmap": ["my_custom_module.php"], "exclude-from-classmap": []
},
"config": {
"preferred-install": "dist"
},
"type": "prestashop-module"
}
You launch composer install from the my_custom_module dir and the
autoloader.php is generated under the vendor dir.
Et voilà , now Prestashop will load your module (if it has been activated)
and you can use the power of Symfony and use modern controllers in
Prestashop.All the above stuff is explained in the Prestashop dev docs
https://devdocs.prestashop.com/1.7/modules/concepts/controllers/admin-controllers/
.
Take the time to read the dev docs.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/PrestaShop/PrestaShop/issues/11596#issuecomment-452005545,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AP5plSQJKYgCRU0maq1T2kfo2HN8v9NBks5vA336gaJpZM4Y-rO2
.
Nice tip! This docs are pretty new, didn't saw them before
Yes it comes with the 1.7.5.0 released on middle of december.
about doctrine, you used your own module config.yml or prestashop one? Becouse i think that prestashop one can work easly, but would be nicer to have module one too.
I use the prestahop one.
Currently prestashop doesn't read any config file in the module dir. I think it's the main purpose of this issue, give the ability of set and read a module configuration file.
If prestashop don't read module configuration file, then how to add custom console commands?!
@matks what do you think about creating official repo with symfony-skeleton-module?
i used the service, but it was a legacy issue:
I was running a custom command (so full symfony)
But You need to include include(_PS_ROOT_DIR_.'/config/config.inc.php') if you want to use prestashop DB etc..
I thinks that this must be indicated on the docs
we need also to check what it means: where can we declare repositories, how to deal with migrations
@matks Not sure but dealing with module db migrations within prestashop's could be a lot of work, no ? A module developer could just do as psyray did : generate the migration using the diff
command and then use the current upgrade mechanism.
Adding module entities should be possible by adding specific compiler passes with a bit of config provided by the module author (maybe a config/doctrine.yml
file with mapping configuration similar to the one from DoctrineBundle.
Would that be an option ?
FYI
I was also able to use the Symfony part & Doctrine entities in the frontend.
According to this post, I've implemented 3 methods in my main module controller (the one with the same name of the module, in the root module dir).
Then in the __construct method I define my service controller.
(...)
use My\Module\Controller\Front\MyFrontController;
class My_Module extends Module implements WidgetInterface
{
(...)
public function __construct()
{
(...)
$this->setService('my.front.controller', new MyFrontController());
(...)
}
/**
* Get Symfony Kernel to use in front office
*
* @return \AppKernel
*/
public static function getKernel(){
// if the singleton doesn't exist
if(!self::$kernel) {
require_once _PS_ROOT_DIR_.'/app/AppKernel.php';
$env = _PS_MODE_DEV_ ? 'dev' : 'prod';
$debug = _PS_MODE_DEV_ ? true : false;
self::$kernel = new \AppKernel($env, $debug);
self::$kernel->boot();
}
return self::$kernel;
}
/**
* Get a specific Symfony service
*
* @param string $service
* @return object
*/
public static function getService($service){
return self::getKernel()->getContainer()->get($service);
}
/**
* Set a Symfony service to use in the front office
*
* @param string $id
* @param object $service
*/
public static function setService($id, $service){
return self::getKernel()->getContainer()->set($id, $service);
}
(...)
}
Then in my front controller (under controllers/front/), I call my Symfony controller in the init method
class My_ModuleFrontModuleFrontController extends ModuleFrontController
{
/**
* @var MyFrontController
*/
private $myFrontController;
public function init() {
parent::init();
$this->myFrontController =My_Module::getService('my.front.controller');
$this->myFrontController->setFrontController($this);
}
(...)
}
And in the initContent method, I pass the request to my Symfony controller which returns vars for the smarty part.
class My_ModuleMyModuleFrontController extends ModuleFrontController
{
(...)
public function initContent()
{
parent::initContent();
$templateVars = [];
if(Tools::getIsset('action')) {
$action = Tools::getValue('action');
$request = Tools::getAllValues();
if(method_exists($this->MyFrontController, $action)) {
$templateVars = $this->MyFrontController->{$action}($request);
if(!is_array($templateVars)) {
header('HTTP/1.1 404 Not Found');
header('Status: 404 Not Found');
$this->context->cookie->disallowWriting();
$this->setTemplate('errors/404');
} else {
$this->context->smarty->assign($templateVars);
$this->setTemplate($this->MyFrontController->getFrontTemplatePath('front/'.$action));
}
}
}
(...)
The method initContent call my Symfony controller by building the method dynamically based on the action part.
_eg_: To generate a link to my module front controller (the prestashop one)
{$link->getModuleLink('my_module', 'front', ['action' => 'myAction', 'id' => $my.id])|escape:'htmlall':'UTF-8'}
So this link call the Symfony method myAction of the myFrontController controller contained in the src folder of my module.
The Symfony controller
namespace My\Module\Controller\Front;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use My\Module\Entity\MyEntity;
use Doctrine\Common\Persistence\ManagerRegistry;
use PrestaShop\PrestaShop\Adapter\Entity\Context;
/**
* Class MyFrontController.
*/
class MyFrontController extends Controller
{
/**
* @var ManagerRegistry
*/
private $em;
/**
* @var \ModuleFrontController
*/
private $moduleFrontController;
/**
* @var MyRepository
*/
private $myRepository;
/**
* @var Context
*/
private $context;
public function __construct() {
$this->em = \My_Module::getService('doctrine')->getManager();
$this->myRepository = $this->em->getRepository(MyEntity::class);
$this->context = Context::getContext();
}
/**
* Return the var to use in the smarty template
* @param array $request
* @return array
*/
public function myAction($request) {
$datas = $this->myRepository->findOneById($request['id']);
return ['datas' => $datas];
}
/**
* Set the module front controller
*/
public function setFrontController($moduleFrontController) {
$this->moduleFrontController = $moduleFrontController;
}
/**
* Get the template path
* @param string $name
* @return string
*/
public function getFrontTemplatePath($name, $modulePath = null) {
$relativePath = 'views/templates/front/'.$name.'.tpl';
if(null !== $modulePath) {
return $modulePath.$relativePath;
}
return 'module:my_module/'.$relativePath;
}
}
With this configuration you could use the Symfony Power in front :)
Doctrine power is really the best part against the Prestashop ObjectModel.
A real productivity boost is done on this part. No need to create ObjectModel for your module classes.
If you want to link an ObjectModel class in your Doctrine entity, I do the following :
Define your property with annotation
use PrestaShop\PrestaShop\Adapter\Entity\Product;
class MyProduct extends ArrayAndObjectAccess
{
(...)
/**
* @var Product
* @todo Change this entity when Prestashop migrate it
*
* @ORM\Column(name="id_product", type="integer", options={"unsigned"=true}, nullable=false)
*/
private $product;
(...)
And your method
(...)
/**
* @return Product|null
* @todo Update getter when Prestashop migrate entity
*/
public function getProduct()
{
if($this->product > 0) {
return new Product($this->product, false, Context::getContext()->language->id, Context::getContext()->shop->id);
}
return null;
}
(...)
So the entity method call will return the ObjectModel or null (same as Doctrine entity behavior)
Not perfect but working.
And when the entity will be migrated to Symfony you just have to change the annotation to define the relationship and the getter to call the property ;)
And last but not least, ObjectModel returns an object usable as array, but Doctrine entity returns only an object.
So to make Doctrine entity usable as array you could use this class and extends your Doctrine entities with it and you can access entities as array :)
<?php
namespace My\Module\Tools;
class ArrayAndObjectAccess implements \ArrayAccess {
/**
* Assigns a value to the specified offset
*
* @param string The offset to assign the value to
* @param mixed The value to set
* @access public
*/
public function offsetSet($offset,$value) {
$this->{"set$offset"}($value);
}
/**
* Whether or not an offset exists
*
* @param string An offset to check for
* @access public
* @return boolean
*/
public function offsetExists($offset) {
$value = $this->{"get$offset"}();
return $value !== null;
}
/**
* Unsets an offset
*
* @param string The offset to unset
* @access public
*/
public function offsetUnset($offset) {
$this->{"set$offset"}(null);
}
/**
* Returns the value at specified offset
*
* @param string The offset to retrieve
* @access public
* @return mixed
*/
public function offsetGet($offset) {
return $this->{"get$offset"}();
}
}
I hope to have been clear.
Enjoy
Hi @kermorgant,
I am currently working on the migration of one of our 1.6 module to 1.7
And I'm gonna use it as an opportunity to be able to use Doctrine in our modules.
I like your proposal with the doctrine path and your doctrine.yml config, however I had an even broader integration in mind. We already add a system to declare symfony services in modules, then we added a system to declare symfony routes in our modules, now we want to define doctrine configuration in our modules...
I have the feeling that we are going to ingrate all symfony components piece by piece.. so each time something will be lacking we will have to modify the core again, and while we do this module developers can only wait..
So what I propose is one and only solution, integrate a config.yml inside the modules so that modules can extend and override any Symfony config themselves. I would fo it by modifying AppKernel::registerContainerConfiguration
which will load any config.config.yml
file present in the modules folders.
What do you think of this solution?
Besides I looked at your proposal to manage Symfony controller for the frontend. Although I would love to be able to use them in this case I wonder if it's relevant? Since you need to have a legacy controller as a bridge it looks like there is some heavy work for few results.
The saddest thing is you can't return a Response like you usually do with a Symfony controller, but instead you need to divide your controller into two methods, one for the variables and one for the template. Because you need to return something compatible with smarty.
And most of all I am worried about the performance of this solution. Did you tests it with Blackfire or any other monitoring/performance tool?
Besides I looked at your proposal to manage Symfony controller for the frontend. Although I would love to be able to use them in this case I wonder if it's relevant? Since you need to have a legacy controller as a bridge it looks like there is some heavy work for few results.
Not totally agree with you, it's not an heavy work (it takes ~6 hours to create the bridge system), and the result is : more productivity and it's reusable as is in another module.
ObjectModel class creation is really an heavy work, create properties with proprietary type for property, queries, sync with DB tables...
Besides we have services, annotations, namespaces, migrations, getters, setters, __toString, Doctrine collections management, Doctrine repositories with doctrine builder....an so on
Many improvements for the developer life which focus him on the project added value, the main purpose of a framework like Symfony.
The saddest thing is you can't return a Response like you usually do with a Symfony controller, but instead you need to divide your controller into two methods, one for the variables and one for the template. Because you need to return something compatible with smarty.
You're right, the missing Response/Route is the main problem, but it seems to be the only part at this time of my module coding.
And while the front use Smarty instead of Twig I can't do otherwise.
In my solution all of my use cases are managed by the Symfony part, truncated, but efficient.
And I will be frank, I hate the ObjectModel :)
He has served us well in the past, but now it is obsolete, it's time to change. It's a lot of time consuming if you have a module with a complex database relationships, and it's my case.
Also I love Symfony, and my knowledge is good enough to know that I will save a lot of time to maintain and evolve my module while it's in production.
And most of all I am worried about the performance of this solution. Did you tests it with Blackfire or any other monitoring/performance tool?
At this point, no, but I don't think the performance will be bad with Doctrine and Symfony.
Prestashop core is so old, that I think the bottleneck should be on this part not in the Symfony part.
I frequently use Xdebug with KcacheGrind to identify bottleneck in my module code for a long time so if there is a bottleneck I will solve it.
I didn't search a way to display the symfony debug bar in front, I don't know if it's possible.
If I could display it I could identify bad queries, time execution, controller error...
But I'm not, currently, at the optimization time. I will make a feedback later on this part.
From your knowledge did you know if I could display the debug bar ? And how ?
I completely agree with you about ObjectModel
and Doctrine
and I think we could gain in productivity if we had this feature. It's just the way you twist the legacy framework to integrate a symfony controller inside it that "bothers" me.
I think it would be better if we could simply use the controller via a Symfony routing without using this legacy bridge. But sadly it is not possible yet in PrestaShop. I think you could use doctrine in a legacy controller without a Symfony controller no?
Although, trust me, I would love to have full Symfony available on front, it is not possible for now because the team focuses on migrating the back-office. And the integration of Symfony in the front is kept at the minimum because it can have a huge impact on performance and we need to keep the core front code performant for the merchants.
About the debug toolbar, I'm not sure it's possible I believe you need to have a twig layout to integrate it easily and since we are still using legacy framework and smarty it seems complicated. The framework doesn't even manage the request so you can't even find the X-Debug-Token-Link
header in the request.
I think it would be better if we could simply use the controller via a Symfony routing without using this legacy bridge. But sadly it is not possible yet in PrestaShop. I think you could use doctrine in a legacy controller without a Symfony controller no?
Yes, I could, but Symfony controller is more powerful, and I want to keep all my code in one place, in the src folder. Easy to move ;)
The only task of the legacy controller is Request in, and Smarty vars out to display content.
All the business logic is in the symfony part.
So when front will be in full Symfony, only the templates will be migrated.
Although, trust me, I would love to have full Symfony available on front, it is not possible for now because the team focuses on migrating the back-office. And the integration of Symfony in the front is kept at the minimum because it can have a huge impact on performance and we need to keep the core front code performant for the merchants.
I understand, it's a hard stuff.
About the debug toolbar, I'm not sure it's possible I believe you need to have a twig layout to integrate it easily and since we are still using legacy framework and smarty it seems complicated. The framework doesn't even manage the request so you can't even find the
X-Debug-Token-Link
header in the request.
Thanks for the reply, I will investigate this part later
I understand that you want to use Symfony controller, but if you need a bridge for that you don't necessarily need to use smarty and divide your controller in two parts, besides you can't use twig which is a bummer.
A more efficient way to implement your bridge could be to use your Symfony controller as a usual, using twig rendering and returning a response, then your PrestaShop bridge's job would be to render this response, something like:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class My_ModuleMyModuleFrontController extends ModuleFrontController
{
(...)
/**
* @var Response
*/
private $symfonyResponse;
public function initContent()
{
if(Tools::getIsset('action')) {
$action = Tools::getValue('action');
$request = Request::createFromGlobals();
if(method_exists($this->MyFrontController, $action)) {
$this->symfonyResponse = $this->MyFrontController->{$action}($request);
}
}
}
public function display()
{
if(!$this->symfonyResponse || !$this->symfonyResponse->isSuccessfull()) {
header('HTTP/1.1 404 Not Found');
header('Status: 404 Not Found');
$this->context->cookie->disallowWriting();
$this->setTemplate('errors/404');
} else {
$this->symfonyResponse->send();
}
}
(...)
}
you could even create an abstract SymfonyModuleController
class to reuse easily this behaviour
abstract class SymfonyModuleController extends ModuleFrontController {
/**
* @var string
*/
protected $symfonyControllerServiceId;
/**
* @var Controller
*/
protected $symfonyController;
public function __construct($symfonyControllerServiceId) {
parent::__construct();
$this->symfonyControllerServiceId = $symfonyControllerServiceId;
}
public function init() {
parent::init();
$this->symfonyController = My_Module::getService($this->symfonyControllerServiceId);
$this->symfonyController->setFrontController($this); //Although I'm not sure why you need the legacy controller in your symfony controller
}
}
Thanks for this great improvement. My project is too advanced with Smarty and I need to deliver it ASAP.
But I think I will rewrite it in Twig very soon.
At this point, no, but I don't think the performance will be bad with Doctrine and Symfony.
This is indeed really important as Front Office performance is critical for the customers
Do you have time next week to discuss the use of Symfony framework in Symfony? If you need to support Twig templates, you can inject the Twig service and do: My_Module::getService('twig')->render(...) like you usually do in Symfony applications :angel:
At this point, no, but I don't think the performance will be bad with Doctrine and Symfony.
This is indeed really important as Front Office performance is critical for the customers
Thanks for your feedback, I will take care of it.
Do you have time next week to discuss the use of Symfony framework in Symfony?
@mickaelandrieu I think you would say "Symfony framework in Prestashop", no ?
Otherwise it's a non-sense :)
Yes, when ?
If you need to support Twig templates, you can inject the Twig service and do: My_Module::getService('twig')->render(...) like you usually do in Symfony applications angel
At this time, I don't really need to use Twig template, but maybe later it could be really interesting to have a full Symfony module for front and back (with a little bridge to maintain Prestashop front legacy usage)
@jolelievre Thanks for your feedback.
I understand your wish for a broader integration (which I would welcome as well), but as this issue had got so far as to be planned for 1.7.6 (a pity it just got delayed :-(), it made sense to push that forward on its original scope.
Otherwise, I'm affraid this would need some more time for analysis as it might be a bit contradictory with their strategy as eternoendless stated :
a custom shop should be able to customize stuff as much as they need, but using our pre-defined paths as much as possible
Hi @kermorgant
you are right about focusing on only Doctrine for now. Besides we discussed about the 1.7.6 roadmap yesterday with the team and integrating a full config management will take too much time to be introduced in the 176.
I hope you don't mind I took the liberty to create another PR on this subject, besides the Doctrine compiler pass there is a lot of work to do to allow the service on front and in legacy controllers.
Here is my PR https://github.com/PrestaShop/PrestaShop/pull/12564
I favored Doctrine annotation rather than yml or xml configuration, I think most Prestashop modules will be more at ease with this kind of configuration since they are used to manage everything in their ObjectModel class. Besides I think it's preferable to limit the scope of this feature to minimize the complexity for developers who are not used to Doctrine (three ways to configure your entities can be overwhelming). It is based on the convention that Entities have to be in the src/Entity
folder of the modules.
That's just a suggestion of mine of course, it is more than open to discussion. Let's keep in mind that more advanced doctrine configuration (including yml and xml configuration) will be available when we offer the possibility to have a complete config file in the modules. It would be a nice feature for 177 I think.
@jolelievre no worry about the PR, I'm actually glad someone else can take care of it :-)
I think the way the doctrine entities are declared is a minor detail at this stage. I was afraid this feature would not be part of 1.7.6 (I misinterpreted the situation) so if that happens, any approach is good I guess.
But for the future, I feel giving a bit of control on where entities are stored and how they are declared would be a good thing (there can be good reasons for having separate doctrine entity configuration)
I completely agree with you, which is why I proposed to allow overriding the framework config with a config.config.yml
file in the modules. I will try to convince and integrate this in the 177 scope.
For now let's keep this doctrine feature simple, there are still questions about the PR. Among other things allowing doctrine on front side which is a very sensitive part. Feel free to take part in the PR discussion if you have any feedback this will help convincing the team ^^
yep, I added this comment about offering module authors a way to choose between annotations, xml or yml.
That's something that I could do after your PR is merged.
@kermorgant PR is merged ;)
I think we can close this issue after I rename it "Part 1", and we'll have another issue for next release
Hi @matks
There was this discussion in the PR review, about yml/xml/annotations.
I've not followed things closely in the recent days, but I understood that entities in module could now be created by following conventions (zero configuration), and that is important to limit confusion.
I could still see myself proposing an option for allowing xml, but only if I had myself a need to override a model. If not, I should be fine with annotations too :-).
What about doctrine events?
Actually the HasLifecycleCallbacks work, but services with doctrine.event_listener tag, don't.
HasLifecycleCallbacks is on some use case, but the miss of service access on the callback, make it too limited.
Any plan to implement it?
I'm also using doctrine to manage my own module entities (specific to 1 site) and wonder if modifying the app config.yml is an ok thing to do.
Could the file be overriden by a prestashop upgrade ?
Hi,
I have myself modified the app/config.yml to add my doctrine config, but it was before this PR was merged https://github.com/PrestaShop/PrestaShop/pull/12564
Now you can use Doctrine directly by configuring it in your module.
Look at this docs : https://devdocs.prestashop.com/1.7/modules/concepts/doctrine/
And this module for a working use case : https://github.com/PrestaShop/productcomments/
Indeed Thanks!!
I originally had my entities in a non-default folder (/src/Entity
), which is why mappings were not registered.
Most helpful comment
I will follow your advice and wrap ObjectModel into a class.
Thanks for your reply.
Anyway Prestashop is on the good way, thanks too for your work :+1: