magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.47k stars 9.29k forks source link

DataObjectHelper wrong snake case #35457

Open sheepfy opened 2 years ago

sheepfy commented 2 years ago

check this file: https://github.com/magento/magento2/blame/5d9fe40c09f56317fb72752fefd00e42ec90431e/lib/internal/Magento/Framework/Api/DataObjectHelper.php#L304

Line 304 says that each class method should get an "_" before upper letter.

Have a class with a method "setFirstASecond()" Now execute code from line 307 with the given "setFirstASecond" method as input:

strtolower(pregreplace(['/(^|,)(?!set)[^,]*/S','/(.)([A-Z])/S', '/(^|,)set/iS', '/(^|,)is([^,]+)/is'], ['', '$1$2', '$1', '$1$2,is_$2'], 'setFirstASecond'))

Notice the output: "first_asecond"

Question: Where is the "_" before the upper S letter? Or is this intended?

I have noticed this after I've done the upgrade from 2.4.3-p1 to 2.4.4 and after saving an entity from admin, some data got lost.

Population of the object data was done with: $this->dataObjectHelper->populateWithArray(...)

Updates: I tried to product in $data the key according to the preg_replace. So I have $data['first_asecond'] = 'X' and also the Interface have the method setFirstASecond() defined. Then DataObjectHelper calls $methodName = SimpleDataObjectConverter::snakeCaseToUpperCamelCase($key); at line 132. Having "FirstAsecond" as a camelCase conversion. Which then tries to set the value into the object, arrives in here: vendor/magento/framework/Reflection/MethodsMap.php at line 87. At line 87, we will have methods from interface set into an array as keys, in our case, key will be setFirstASecond . Then we will get "underfined key setFirstAsecond because of the lower S.

If you need stepts to reproduce:

  1. create interface with setter method like expalined above, example: public function setFirstASecond($value);
  2. create class Whatever extends AbstractModel implements WhateverInterface
  3. Go somewhere where you can execute some piece of code and populate from a given data array, $data the $object via $this->dataObjectHelper->populateWithArray(...) example snippet: $data = ['first_asecond' => 'somevalue']; // or $data = ['first_a_second' => 'somevalue']; , you got the point. $object = $this->objectFactory->create(); $this->dataObjectHelper->populateWithArray($object, $data, WhateverInterface::class);

Also please note that if you do: $object->setData('first_asecond', 'somevalue'); then $object->getFirstASecond() -> outputs nothing, but $object->getFirstAsecond() -> outputs 'somevalue'

m2-assistant[bot] commented 2 years ago

Hi @sheepfy. Thank you for your report. To speed up processing of this issue, make sure that you provided the following information:

Make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce. To deploy vanilla Magento instance on our environment, Add a comment to the issue:

@magento give me 2.4-develop instance - upcoming 2.4.x release

For more details, review the Magento Contributor Assistant documentation.

Add a comment to assign the issue: @magento I am working on this

To learn more about issue processing workflow, refer to the Code Contributions.


:clock10: You can find the schedule on the Magento Community Calendar page.

:telephone_receiver: The triage of issues happens in the queue order. If you want to speed up the delivery of your contribution, join the Community Contributions Triage session to discuss the appropriate ticket.

:pencil2: Feel free to post questions/proposals/feedback related to the Community Contributions Triage process to the corresponding Slack Channel

m2-assistant[bot] commented 2 years ago

Hi @engcom-Delta. Thank you for working on this issue. In order to make sure that issue has enough information and ready for development, please read and check the following instruction: :point_down:

engcom-Delta commented 2 years ago

Hi @sheepfy , Thank you for raising an issue. Happy to assist you. Kindly request you to provide issue description, steps to reproduce, actual results, expected results and screenshots if required. Regards,

sheepfy commented 2 years ago

@engcom-Delta I just explained. See issue description.

sheepfy commented 2 years ago

@engcom-Delta I've added more info about the issue.

engcom-Delta commented 2 years ago

@sheepfy ,Thank you we will verify the issue and update you .

m2-assistant[bot] commented 2 years ago

Hi @engcom-Hotel. Thank you for working on this issue. In order to make sure that issue has enough information and ready for development, please read and check the following instruction: :point_down:

engcom-Hotel commented 2 years ago

Hello @sheepfy,

Thanks for the reporting and collaboration!

We have tried to reproduce the issue in Magento 2.4-develop branch by following steps:

  1. Create a function in class app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php with the name suggested in the main description i.e. setFirstASecond and setFooBarBar.
  2. Used Xdebug to check the output of method getSetters from lib/internal/Magento/Framework/Api/DataObjectHelper.php class.
  3. Please find below the output of the same: 1

As a conclusion, the function getSetters is not working as expected for 2 consecutive Capital letters like setFirstASecond but if the string is like this setFooBarBar then it is working fine.

Hence confirming the issue.

Thanks

github-jira-sync-bot commented 2 years ago

:white_check_mark: Jira issue https://jira.corp.magento.com/browse/AC-3146 is successfully created for this GitHub issue.

m2-assistant[bot] commented 2 years ago

:white_check_mark: Confirmed by @engcom-Hotel. Thank you for verifying the issue.
Issue Available: @engcom-Hotel, You will be automatically unassigned. Contributors/Maintainers can claim this issue to continue. To reclaim and continue work, reassign the ticket to yourself.

sheepfy commented 2 years ago

@engcom-Hotel Thanks! As a quick search on google, got this converter tho: https://textedit.tools/snakecase

image

martin-cod commented 2 years ago

There is one more addition to the issue related to SimpleDataObjectConverter utility class

image

You can check Laminas NamingStrategy for reference https://github.com/laminas/laminas-hydrator/blob/4.4.x/src/NamingStrategy/UnderscoreNamingStrategy/CamelCaseToUnderscoreFilter.php

ageffray commented 1 year ago

To fix it you can replace preg_replace( ['/(^|,)(?!set)[^,]*/S','/(.)([A-Z])/S', '/(^|,)set_/iS', '/(^|,)is_([^,]+)/is'], ['', '$1_$2', '$1', '$1$2,is_$2'], implode(',', $dataObjectMethods) )

by

preg_replace( ['/(^|,)(?!set)[^,]*/S','/([A-Z])/S', '/(^|,)set_/iS', '/(^|,)is_([^,]+)/is'], ['', '_$1', '$1', '$1$2,is_$2'], implode(',', $dataObjectMethods) ) in magento/framework/Api/DataObjectHelper.php:307

matthewhaworth commented 1 year ago

This is causing me a problem too, just wanted to re-draw attention to it. I experienced the problem, then came searching and found this.