New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce single unified UpdateProductCommand #30031
Introduce single unified UpdateProductCommand #30031
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @zuk3975
A few comments but most of them are about naming and namespaces (and suggestions for additional tests ^^), but the generic principle of the whole PR seems good to me!
src/Adapter/Product/Update/ProductBasicInformationPropertyFiller.php
Outdated
Show resolved
Hide resolved
use PrestaShop\PrestaShop\Core\Domain\Product\Command\UpdateProductCommand; | ||
use Product; | ||
|
||
class ProductUpdatablePropertyFiller implements ProductUpdatablePropertyFillerInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add a description for this class explaining how it handles all the sub fillers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking the naming is a bit too long maybe (same for the interface and related variables), maybe ProductFiller
and ProductFillerInterface::fillProperties
would be enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would still like to emphasize that it returns the properties for update 🤔
So either a class or a method could mention the updatable props. (maybe the method?). Or you think thats not necessary?
use PrestaShop\PrestaShop\Core\Domain\Product\Command\UpdateProductCommand; | ||
use Product; | ||
|
||
class ProductOptionsPropertyFiller implements ProductUpdatablePropertyFillerInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add descriptions on all the new class, even a simple one at least explaining which sub domain this filler handles
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I think these classes should be unit tested, their responsibility is quite simple and scope:
- fill the fields
- return array indicating which fields have been update
This makes them perfect candidates for unit testing, the two you handled don't have that many specific rules (although link_rewrite is not that intuitive) but other like SEO and Prices sub domains have some twisted rules sometimes which would be worth testing to avoid regressions.
It may be a bit in doublons with the behat tests, but it's not the same thing. Behat tests will validate the behaviour, while unit tests here would test our implementation.
src/Adapter/Product/Update/ProductUpdatablePropertyFillerInterface.php
Outdated
Show resolved
Hide resolved
...aviour/Features/Context/Domain/Product/UpdateProduct/AbstractUpdateOptionsFeatureContext.php
Show resolved
Hide resolved
...n/Behaviour/Features/Context/Domain/Product/UpdateProduct/OptionsAssertionFeatureContext.php
Show resolved
Hide resolved
...viour/Features/Context/Domain/Product/UpdateProduct/UpdateBasicInformationFeatureContext.php
Show resolved
Hide resolved
...tion/Behaviour/Features/Context/Domain/Product/UpdateProduct/UpdateOptionsFeatureContext.php
Show resolved
Hide resolved
src/Core/Form/IdentifiableObject/CommandBuilder/Product/UpdateProductCommandsBuilder.php
Show resolved
Hide resolved
0be5a5b
to
65e1e11
Compare
$product, | ||
$command, | ||
[ | ||
'available_for_order', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping @jolelievre Idk if we should care to check if new value from command changes the previous one?
bcuz thats why this test case seems abit strange (by default $product->show_price and $product->available_for_order is true. So when we set AvailableForOrder to true, we are still updating the field (even though we are updating it with the same value). Same happens with other fields, its just more visible with show_price and available_for_order, because the $show_price value is the only one that is not updated if its not changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understand everything 😅 we should discuss this live
e65014a
to
133d5a7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @zuk3975
The whole architecture is fine for me, the only comments are about naming, we should discuss this live after next standup it'll be more efficient than via review comments
classes/shop/Shop.php
Outdated
@@ -397,7 +397,7 @@ public static function initialize() | |||
); | |||
|
|||
$isAllShop = 'all' === $id_shop; | |||
$isApiInUse = defined('_PS_API_IN_USE_') && _PS_API_IN_USE_; | |||
$isApiInUse = defined('_PS_API_IN_USE_') && _PS_API_IN_USE_ === true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this was needed since it's only use for Webservice context and the only value it can have so far true
anyway
PrestaShop/webservice/dispatcher.php
Line 32 in 31bdccd
define('_PS_API_IN_USE_', true); |
Is it really in your PR's scope?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, no I fixed it in another one. Forgot here, thanks 👍
/** | ||
* Fills product properties which can be considered as a basic product information | ||
*/ | ||
class ProductBasicInformationPropertyFiller implements ProductUpdatablePropertyFillerInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class ProductBasicInformationPropertyFiller implements ProductUpdatablePropertyFillerInterface | |
class BasicInformationFiller implements ProductFillerInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking of ways to reduce all the namings which are quite long:
- the method name in the interface is already
fillUpdatableProperties
so the UpdateableProperty part can be removed in class names and interface - since we already are in product namespace having product prefix everywhere is a bit redundant (although I kept it in
ProductFillterInterface
to avoid confusion with future potentialFillerInterface
used for other entites
/** | ||
* Fills product properties which can be considered as product options | ||
*/ | ||
class ProductOptionsPropertyFiller implements ProductUpdatablePropertyFillerInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class ProductOptionsPropertyFiller implements ProductUpdatablePropertyFillerInterface | |
class OptionsFiller implements ProductFillerInterface |
* | ||
* All the internal property fillers are split just to contain less code and be more readable (because the Product contains many of properties). | ||
*/ | ||
class ProductUpdatablePropertyFiller implements ProductUpdatablePropertyFillerInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class ProductUpdatablePropertyFiller implements ProductUpdatablePropertyFillerInterface | |
class ProductFiller implements ProductFillerInterface |
/** | ||
* Responsible for filling up the Product with the properties which have to be updated | ||
*/ | ||
interface ProductUpdatablePropertyFillerInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interface ProductUpdatablePropertyFillerInterface | |
interface ProductFillerInterface |
prestashop.adapter.product.update.product_updatable_property_filler: | ||
class: PrestaShop\PrestaShop\Adapter\Product\Update\ProductUpdatablePropertyFiller | ||
arguments: | ||
- !tagged core.product_updatable_property_filler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made some other comments regarding the interface naming, this tag renaming would make even more sense if the interface is renamed
use PrestaShop\PrestaShop\Adapter\Product\Update\Filler\ProductUpdatablePropertyFillerInterface; | ||
use PrestaShop\PrestaShop\Adapter\Tools; | ||
|
||
class ProductBasicInformationPropertyFillerTest extends PropertyFillerTestCase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class ProductBasicInformationPropertyFillerTest extends PropertyFillerTestCase | |
class BasicInformationFillerTest extends ProductFillerTestCase |
use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopConstraint; | ||
use Product; | ||
|
||
abstract class PropertyFillerTestCase extends TestCase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
abstract class PropertyFillerTestCase extends TestCase | |
abstract class ProductFillerTestCase extends TestCase |
abstract public function getDataForTestFillsUpdatableProperties(): iterable; | ||
|
||
abstract public function getFiller(): ProductUpdatablePropertyFillerInterface; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
abstract public function getDataForTestFillsUpdatableProperties(): iterable; | |
abstract public function getFiller(): ProductUpdatablePropertyFillerInterface; | |
abstract protected function getDataForTestFillsUpdatableProperties(): iterable; | |
abstract protected function getFiller(): ProductUpdatablePropertyFillerInterface; |
These two could and should be protected no? Maybe getDataForTestFillsUpdatableProperties
is a bit different since a data provider so I understood we may be forced to keep it public But for getFiller
it seems we don't need to have it public, or am I missing something?
$product, | ||
$command, | ||
[ | ||
'available_for_order', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understand everything 😅 we should discuss this live
This reverts commit 1d1306a.
4a56bb6
to
0c17d4c
Compare
src/PrestaShopBundle/Resources/config/services/core/form/command_builder.yml
Outdated
Show resolved
Hide resolved
0c17d4c
to
5e0e8f2
Compare
e386a01
to
07e2bd8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @zuk3975
prestashop.adapter.product.update.filler.product_filler: | ||
class: PrestaShop\PrestaShop\Adapter\Product\Update\Filler\ProductFiller | ||
arguments: | ||
- !tagged core.product_filler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I Think the tag name should start by prestashop (like prestashop.core.product_filler)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was insipired by core.product_command_builder
so I didn't think too much.
I think its a question to @jolelievre (I see other older services using prestashop prefix like prestashop.core.command_bus
) maybe indeed we shoul rename these 2 new concepts with the prestahop prefix too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we use core
it implicitly relates to prestashop core, but I guess we can be more explicit on this one I don't mind you can replace it if you prefer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't care either, so as its not a blocker I prefer not to change anything now. But we can still do it when migrating other commands if decided
/** | ||
* Fills product properties which can be considered as a basic product information | ||
*/ | ||
class BasicInformationFiller implements ProductFillerInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the whole point of having *FillerInterface
files and classes.
Why don't we fetch the product and map data inside ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
purely just to keep them small I guess. Cuz we will have like 5-6 of those classes (and we already had all the logic taken from dedicated command handlers that used it before).
Do you think its an overengineering?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea was indeed to avoid having one mega filler with 4000 lines of code, and to be able to work on remaining pieces more easily in multiple PRs. But maybe at the end this should be all done inside one, we could refacto this and merge them all into one We can discuss this tomorrow I guess
Thanks @zuk3975 |
How to test
Locally it can be tested by uncomenting tags of product_commands_builder (in Resources/config/services/core/form/command_builder.yml prestashop.core.form.command_builder.product.update_product_commands_builder) and making sure that the UpdateProductCommand appears in the list of generated commands in Core/Form/IdentifiableObject/DataHandler/ProductFormDataHandler::update(). Also related behat scenarios can be run using these commands in terminal: