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
Migrate attribute group edit #31502
Migrate attribute group edit #31502
Conversation
f622b04
to
e01842f
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.
integration tests are red, they must be updated due to your migration I guess 👍
misclick I wanted to comment-review
public const ATTRIBUTE_GROUP_TYPE_SELECT = 'select'; | ||
|
||
public const ATTRIBUTE_GROUP_TYPE_RADIO = 'radio'; | ||
|
||
public const ATTRIBUTE_GROUP_TYPE_COLOR = 'color'; |
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.
should introduce VO AttributeGroupType which would also validate itself in constructor
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.
Indeed it can be interesting to have such VOs that ensures the limited choices of this field
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.
Good idea! Implemented it
try { | ||
$attributeGroup = new \AttributeGroup($attributeGroupId->getValue()); | ||
} catch (PrestaShopException $e) { | ||
throw new AttributeGroupException('Failed to create new attribute group', 0, $e); | ||
} | ||
|
||
if ($attributeGroup->id !== $attributeGroupId->getValue()) { | ||
throw new AttributeGroupNotFoundException(sprintf('Attribute group with id "%s" was not found.', $attributeGroupId->getValue())); | ||
} | ||
|
||
return $attributeGroup; |
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.
inject PrestaShop\PrestaShop\Adapter\AttributeGroup\Repository\AttributeGroupRepository
and a new method if it doesn't yet exist get(AttributeGroupId $attributeGroupId, ShopId $shopId): AttributeGroup
and use it here instead
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 right I didn't remember but a repository for this entity already exists
class AttributeGroupRepository extends AbstractMultiShopObjectModelRepository |
So you should use and improve it to match your needs here (creation, update, get entity), most of the code you are using here is actually factorized and mutualized vie the abstract module repository helper methods like getObjectModel
throw new AttributeGroupConstraintException('Invalid attribute group data', AttributeGroupConstraintException::INVALID_NAME); | ||
} | ||
|
||
if (false === $attributeGroup->update()) { |
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.
Im pretty sure this could also be used from repository. as well as the validations (same as in other subdomains like product) object model validator can check the fields it already has some methods encapsulated with correct exception throws etc.
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.
Indeed you should use an ObjectModel repository here as well
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | ||
*#} | ||
|
||
{% set layoutTitle = 'Add a new attribute group'|trans({}, 'Admin.Catalog.attribute') %} |
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 move the layoutTitle to controller and name it New attribute
to keep consistent with #31322, the wording is validated.
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.
Good call, so @JevgenijVisockij this should be a template variable set in the controller when you are rendering the page
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | ||
*#} | ||
|
||
{% set layoutTitle = 'Edit: %name%'|trans({'%name%': attributeGroupName}, 'Admin.Actions') %} |
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 move the layoutTitle to controller and name it Editing attribute %name%
to keep consistent with #31322, the wording is validated.
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.
Agreed, except it should be Aditing attribute group %name%
here, this PR targets the AttributeGroup
entity not the Attribute
one
|
||
<div class="card"> | ||
<h3 class="card-header"> | ||
{{ 'Attribute Group'|trans({}, 'Admin.Catalog.Attribute') }} |
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.
{{ 'Attribute'|trans({}, 'Admin.Catalog.Attribute') }}
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 this new wording is more adapted, to understand the difference between Attribute group and its contained Attributes
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.
So to clarify it should stay as Attribute group right?
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.
@jolelievre @JevgenijVisockij @l-delin It has always been Attribute
and Attribute value
and I think it should stay like that.
It's called Attribute group
only in the code and in the database.
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.
Can we wait for @jolelievre review aswell? Im kinda not sure which things we want to require and which not.
I added couple comments which would follow the same principle as we recently done with product page, but don't rush with them.
I have couple doubts, e.g. if we need to use shop constraint for GetAttributeGroupCommand, or we should use the ShopId? because query will always need to get the values only from one shop, so the shopGroup and allShops constraints would become useless (futhermore the attributeGroup doesn't have "default shop id" in database as product does, so what would be the value of shopId when allshops or group shop constraint is given? (it would end up taking first random shop then?) . Anyway I think it may be nice to have a meetup and align before we start requesting different things. It would also apply to other migration PR's
throw new AttributeGroupConstraintException('Invalid attribute group data', AttributeGroupConstraintException::INVALID_NAME); | ||
} | ||
|
||
if (false === $attributeGroup->add()) { |
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.
this part should also be moved to a new repository method "create({all the required props}): Product"
* | ||
* @throws AttributeGroupConstraintException | ||
*/ | ||
public function __construct(int $attributeGroupId, array $localizedNames, array $localizedPublicNames, string $type, array $shopAssociation = []) |
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.
split to multiline
src/Core/Domain/AttributeGroup/ValueObject/AttributeGroupId.php
Outdated
Show resolved
Hide resolved
src/Core/Form/IdentifiableObject/DataProvider/AttributeGroupFormDataProvider.php
Show resolved
Hide resolved
src/Core/Form/IdentifiableObject/DataProvider/AttributeGroupFormDataProvider.php
Show resolved
Hide resolved
src/Core/Form/IdentifiableObject/DataProvider/AttributeGroupFormDataProvider.php
Show resolved
Hide resolved
@@ -537,6 +537,12 @@ services: | |||
|
|||
PrestaShopBundle\Form\Admin\Type\AmountCurrencyType: | |||
|
|||
PrestaShopBundle\Form\Admin\Sell\Catalog\AttributeGroupType: | |||
public: 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.
im pretty sure it can also be autowired and private
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.
Private for sure, autowire why not it won't bring much since you still need to manually define $isMultistoreEnabled
But it can anticipate future modifications
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.
Romeved public true, but is autwire needed? there defaults autowire: true at the top of the file
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 if there is default autowire:true then its all good (didn't see that)
src/PrestaShopBundle/Resources/config/services/core/form/form_data_provider.yml
Show resolved
Hide resolved
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.
Ok so after brief discussion with @jolelievre you could address my comments. It is better if we implement those repositories/validators and shopId explicitly
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.
actually unlike what I though initially and what @zuk3975 suggested, I don't think we need a shopId or a ShopConstraint inside the commands/queries for this Entity.
It's not like for product where the shop context changes the entity content completely (because many things are editable based on shop context and override many values). For this entity it's actually much simpler it only handles an association between the entity and the shops, but the content doesn't change. So you only need to handle in update (and potentially creation) to edit the list of associated shops.
], | ||
); | ||
|
||
new window.prestashop.component.ChoiceTree('#attribute_group_shop_association').enableAutoCheckChildren(); |
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 blocking but could you move these selectors into a separate mapping file, please? It makes it easier to centralize them and modify them when a refacto/modification is needed
src/Adapter/AttributeGroup/CommandHandler/AddAttributeGroupHandler.php
Outdated
Show resolved
Hide resolved
Ok sorry for confusion, I agree. |
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 @JevgenijVisockij
sorry for all the comments again 😅
throw new AttributeGroupConstraintException('Invalid attribute group data', AttributeGroupConstraintException::INVALID_NAME); | ||
} | ||
|
||
if (false === $attributeGroup->update()) { |
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.
Indeed you should use an ObjectModel repository here as well
try { | ||
$attributeGroup = new \AttributeGroup($attributeGroupId->getValue()); | ||
} catch (PrestaShopException $e) { | ||
throw new AttributeGroupException('Failed to create new attribute group', 0, $e); | ||
} | ||
|
||
if ($attributeGroup->id !== $attributeGroupId->getValue()) { | ||
throw new AttributeGroupNotFoundException(sprintf('Attribute group with id "%s" was not found.', $attributeGroupId->getValue())); | ||
} | ||
|
||
return $attributeGroup; |
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 right I didn't remember but a repository for this entity already exists
class AttributeGroupRepository extends AbstractMultiShopObjectModelRepository |
So you should use and improve it to match your needs here (creation, update, get entity), most of the code you are using here is actually factorized and mutualized vie the abstract module repository helper methods like getObjectModel
public const ATTRIBUTE_GROUP_TYPE_SELECT = 'select'; | ||
|
||
public const ATTRIBUTE_GROUP_TYPE_RADIO = 'radio'; | ||
|
||
public const ATTRIBUTE_GROUP_TYPE_COLOR = 'color'; |
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.
Indeed it can be interesting to have such VOs that ensures the limited choices of this field
src/Core/Domain/AttributeGroup/Command/AddAttributeGroupCommand.php
Outdated
Show resolved
Hide resolved
src/Core/Domain/AttributeGroup/Command/EditAttributeGroupCommand.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/Domain/AttributeGroupFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/Domain/AttributeGroupFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/Domain/AttributeGroupFeatureContext.php
Outdated
Show resolved
Hide resolved
src/Core/Domain/AttributeGroup/CommandHandler/EditAttributeGroupHandlerInterface.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Scenario/AttributeGroup/attribute_group_management.feature
Show resolved
Hide resolved
13a400b
to
653691d
Compare
…roupFeatureContext.php Updated array definition in docs Co-authored-by: Julius Žukauskas <31609858+zuk3975@users.noreply.github.com>
Code review changes Co-authored-by: Jonathan Lelievre <jo.lelievre@gmail.com>
Co-authored-by: Jonathan Lelievre <jo.lelievre@gmail.com>
75529bb
to
90dee47
Compare
14d833a
to
d6be6ab
Compare
src/PrestaShopBundle/Resources/config/services/bundle/form/form_type.yml
Outdated
Show resolved
Hide resolved
…m_type.yml Co-authored-by: Jonathan Lelievre <jo.lelievre@gmail.com>
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.
LGTM, thanks @JevgenijVisockij!
Just a small comment but I don't block your PR. ;)
private $attributeGroupRepository; | ||
|
||
public function __construct(AttributeGroupRepository $attributeGroupRepository) | ||
{ | ||
$this->attributeGroupRepository = $attributeGroupRepository; | ||
} |
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.
As we are in develop branch and we drop some PHP versions oldies, you can use constructor property promotion here (and in other handler classes) to simplify some lines.
Anyway, I'm not blocking your PR for this, but it can be a must have now in develop branch PRs! ;)
Test UI and let's go !!!!!! |
@matthieu-rolland UI test are 🔴 :/ |
and it's a merge ! thank you @JevgenijVisockij ! |
7 months until merge 😄 |
UI Tests: https://github.com/matthieu-rolland/ga.tests.ui.pr/actions/runs/6232728862