-
Notifications
You must be signed in to change notification settings - Fork 767
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
CampaignExtensionSettingService::get() returning Types in wrong property? #226
Comments
Hi JC, Thanks for reporting. Best, |
Hi @fiboknacky, I am not sure as I haven't looked into the source code. Here's the essence of what I did: /** @var CampaignExtensionSettingService $campaignExtensionSettingService */
$campaignExtensionSettingService = $this->getService(CampaignExtensionSettingService::class);
$selector = new Selector([
'CampaignId', 'ExtensionType', 'Extensions', 'PlatformRestrictions'
]);
$selector->setPredicates([
new Predicate('CampaignId', PredicateOperator::EQUALS, [$campaignId])
]);
$selector->setPaging(new Paging(0, static::$pageSize));
$page = $campaignExtensionSettingService->get($selector);
var_dump($page->getEntries()); |
Hi JC, Sorry, I wasn't clear. I should've said that "did you use batch job service?". :) Thanks for information. Best, |
This is a specific case of a more generic bug through the objects returned by querying services. Here's an example of a var_dump of an object returned from the AdGroupCriterionService:
Note that there are multiple objects that had the data put in an object property with ".Type" in the name rather than the correct property with "Type" at the end, such as "ComparableValueType" on the Money object, or the "AdGroupCriterionType". This breaks A LOT of the new library, because there is no way to call member functions to get the data, such as on the ProductOfferId object, where you would expect to call ->getProductDimensionType() but it will only ever return a null. The "ProductDimension.Type" property that is created in error and has the correct data can't even be accessed as a property, because having that dot in the name makes it an invalid PHP variable name... A workaround is to call something like get_object_vars($criterion->getCriterion()->getCaseValue())['ProductDimension.Type'] which will return the object's public properties as an associative array, so the data can then be accessed. I haven't poked around a ton to figure out why this is happening, but it appears to originate in src/Google/AdsApi/Common/AdsSoapClient.php. If you var_dump the $response that's returned at line 115, you can see that the SoapClient object's __soapCall method returns the created object representing the XML data with property names that match the XML returned from the SOAP service, but that aren't correct in the context of this library. These errors exist across multiple services and make working with this library difficult until they're fixed. At least there's a workaround, but that means I have to write some code that will break in the future when you fix this bug. A bug fix sooner rather than later would be nice. :) |
Hello @ddeppner Thanks so much for more information from your side. :) We're looking into this and deciding how we should fix this. Usually such properties contain the names of their containing classes, e.g., Best, |
Hi @fiboknacky, For me, I was using it as an identifier when serialized into JSON. During denomalization, when stored in JSON/array/stdClass. the type property can be useful as the class names are not available. I use the other type property (the one with Enum strings) where it is present. On the topic of JSON. All the classes in the new library use protected properties. Whenever I need to cast them to JSON, I need to pass them through a recursive function to ReflectionProperty::setAccessible() all their properties. Any better way to do this? A normalizer/denomalizer will be helpful. I have been writing one for every class that I want to store as JSON. |
I need to crawl through the criteria in an account to determine current bids in a shopping campaign, but in this particular case I need to only work with bids in criteria that are for individual products. But the account could have other bids that are by other dimensions. Also, these ItemId bids are sometimes nested in a structure where the product feed could be split by Brand first, and then within each brand, they could be split by ItemId. So when I SELECT the criteria, I have a problem. I need to select criteria with ProductPartitionType = "UNIT" and that isn't a filterable option. And I need to select criteria representing an actual product, and the only way I see to do that is when the CaseValue is a ProductOfferId type, and that also is not a filterable option. So I'm including PartitionType and CaseValue in my SELECTed fields, then iterating over the list and determining which criteria to operate on. I was previously using the old library where these where represented in a nested array rather than objects with getters and setters. Since I'm used to working with the previous libraries, I was kinda locked into thinking about this as a situation where I needed that field, so my original solution was based on trying to get at that field: get_object_vars($criterion->getCriterion()->getCaseValue())['ProductDimension.Type'] But I take your point. Now that it's using a more modern architecture, I don't need the field to determine the type, I can look at the basename of the class: (new \ReflectionClass($criterion->getCriterion()->getCaseValue()))->getShortName()) get_class() returns the fully qualified class name so it requires more string functions to clean it up, which works but isn't the prettiest thing in the world. instanceof could even be used, but would be problematic because of the versioning in the FQCNs... The thing is, every one of those solutions makes me have to THINK. And they break from what I expect from the previous PHP library. This seems more natural when I'm converting legacy code or quickly typing out something I'd expect to work in new code: $criterion->getCriterion()->getCaseValue()->getProductDimensionType() That doesn't make me have to stop and think. It's just obvious. I think the getSomethingType() functions should be fixed...so the PHP library conforms to what someone would expect reading the API documentation or converting code from the previous library version. But even then it's not perfect because the API docs list the field names with the "dot" in them and when PHP developers go on autopilot and type $obj->getSomething.Type() they'll get an error initially until they dig deeper and figure it out. Why don't you just set the Type field in the constructor of the affected classes or something simple like that? Or include the ReflectionClass code in the getSomethingType() functions so it doesn't even consult the variable. Better yet, just return the name of the class without calling other code—you know it there. :) And then perhaps devote a bit of space in the PHP library documentation to calling out this issue and explaining how it works (regarding the naming of things as "ProductDimensionType" rather than "ProductDimension.Type" since we're using PHP and we need valid variable names, so in this regard the library varies a bit from the API documentation. As more people convert code from the old library to the new, it would be really helpful and save a lot of time. David |
Hello David, Thanks a lot for more feedback and suggestion. Best, |
This is fixed in v28.0.0. |
As you can see below, some of the variables are placed into
PolicyData.Type
andExtensionFeedItem.Type
instead ofPolicyDataType
andExtensionFeedItemType
. The var_dump is the result from executing get using CampaignExtensionSettingService. I am not sure if it affects other services.This causes the methods like ExtensionFeedItem::getExtensionFeedItemType() to not work as those properties are null.
The text was updated successfully, but these errors were encountered: