Skip to content
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

Add fallback for Product_links position attribute if not set in request #12650

Conversation

mohammedsalem
Copy link
Contributor

By setting product_links index on a product via API call, only the first two of each link type are shown in the backend or a in the response of a GET request, although they are correctly added to the database.
The problem was that if the position wasn't set there's no default value or a fallback set in the table "catalog_product_link_attribute_int" for the position attribute.

Description

in SaveHandler class from Magento\Catalog\Model\Product\Link
A check goes in all Products link by type to check if the position were set for all products of this type, else if any wasn't set then do a fallback by array position.

Manual testing scenarios

Before applying PR:

  1. POST/PUT request to following API endpoint with more than 2 linked products (product_links) per link_type without a position: http://dev.domian.com/rest/V1/products/{sku}
  2. Perform a GET request to http://dev.domian.com/rest/V1/products/{sku} - you should only see the first two linked products per link type

After applying PR:

  1. POST/PUT request to following API endpoint with more than 2 linked products (product_links) per link_type without a position: http://dev.domian.com/rest/V1/products/{sku}
  2. Perform a GET request to http://dev.domian.com/rest/V1/products/{sku} - you should see all linked products per link type with a position set.

If the position is set manually in the POST/PUT request for all products of a specific link type, this positions should be taken into account.

@magento-cicd2
Copy link
Contributor

magento-cicd2 commented Dec 12, 2017

CLA assistant check
All committers have signed the CLA.

@mzeis mzeis self-assigned this Dec 13, 2017
@mzeis mzeis added this to the December 2017 milestone Dec 13, 2017
@dmanners
Copy link
Contributor

@mohammedsalem looks like @mzeis is going to process this pull request for you. If you need anything else just drop me or Matthias a message here. Thanks.

@mohammedsalem
Copy link
Contributor Author

@dmanners many thanks, for sure gonna do :)

Copy link
Contributor

@mzeis mzeis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mohammedsalem,

thank you very much for your PR! Please have a look at my code review, there is a minor change I requested.

@@ -18,7 +18,7 @@ class SaveHandler
/**
* @var ProductLinkRepositoryInterface
*/
protected $productLinkRepository;
protected $productLinkRepo;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't rename a protected property as this breaks backwards compatibility (source). I know you get a warning regarding the variable name length, but backwards compatibility is more important than code style.

* @param $linksByType
* @return array
*/
private function isPositionsSet($linksByType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename this to isPositionSet() for consistency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mzeis Changes made
the idea of the plural positions naming instead of singular was that the function returns an array of multi product link type, on the same time wanted to keep the bool naming convention using 'is' or 'has'.

Copy link
Contributor

@mzeis mzeis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the feeling this code could be a little bit more simplified. I'm wondering whether we really need so many iterations to find the links that need their position set.

Please can you consider this change? Also see my comments regarding variable naming.

Thanks!

* @param $linksByType
* @return array
*/
private function isPositionSet($linksByType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking some more about it, it's confusing that a method name starting with is returns an array. It suggests the result should be boolean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming convention will be improved

}

// Do check
$hasPositionLinkType = $this->isPositionSet($linksByType);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's confusing that a variable name starting with has contains an array. The name suggests that it contains a boolean value.

Copy link
Contributor Author

@mohammedsalem mohammedsalem Dec 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it contains an array of boolean values per link type, I had the case that the positions were set for the products in "Related" but not set for products under "Cross sell" and so on,

the same that under on Link type got the case of some products had position attribute and others don't, therefor I had to check if at least one product doesn't have a position under a product Link type all positions under this type will be ignored and user array index instead.

regarding the question whether we need that amount of iterations,
This came from too many use cases and variants of sending data, as I said about some link types aren't used at all others have positions but not for all products, another type with full defined products positions.

@mohammedsalem
Copy link
Contributor Author

mohammedsalem commented Dec 25, 2017

I'll continue working in January because of the holidays,
Merry Christmas 🎄🌟

@okorshenko okorshenko modified the milestones: December 2017, January 2018 Jan 8, 2018
@mzeis
Copy link
Contributor

mzeis commented Jan 20, 2018

Hi @mohammedsalem, please can you provide a way to re-produce the initial problem by posting the calls starting from a fresh 2.2 install? Sorry I only come up with this now.

Copy link
Contributor

@mzeis mzeis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your refactoring! I have two more recommendations, please have a look at the review.


// Build links per type
$linksByType = [];
foreach ($productLinks as $link) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After your last refactoring, we don't need the variable $productLinks in line 72 anymore. Call $entity->getProductLinks() directly in line 72. By doing this, we adhere to the best practice that a variable shouldn't be changed anymore after initialisation.

* @param $links
* @return bool
*/
public function hasPosition($links)
Copy link
Contributor

@mzeis mzeis Jan 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change the scope - methods should be private whenever possible. Also, we now that $links will be an array so we can use type hints.

@mohammedsalem
Copy link
Contributor Author

PR-usecase.json.txt
@mzeis here you are sample request of adding product using Rest API.

@magento-engcom-team
Copy link
Contributor

@mohammedsalem thank you for contributing. Please accept Community Contributors team invitation here to gain extended permissions for this repository.

@ihor-sviziev
Copy link
Contributor

ihor-sviziev commented Jan 31, 2018

FYI In this PR introduced new dependency to constructor, that wasn't used. I removed it inside #13436

ihor-sviziev pushed a commit to ihor-sviziev/magento2 that referenced this pull request Jan 31, 2018
 if position index was not set in API request

 Original PR: magento#12650
@mzeis
Copy link
Contributor

mzeis commented Jan 31, 2018

@mohammedsalem Thanks again for your contribution! Your PR has been merged into 2.2-develop.

@ihor-sviziev Thanks for catching this! The dependency was needed first, but not anymore after the refactoring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants