Closed m2web closed 2 years ago
The answer is in the error message:
Object of class Drupal\node\Entity\Node
that’s what it is, it’s a drupal Node entity, a quick Google should find you what that looks like (sorry on a phone so harder to do from here).
stackoverflow likely has lots of examples of using drupal node hooks, this isn’t anything specific to apic or the developer portal, it’s a standard drupal node entity in a standard drupal node hook.
I’m aware there is quite a learning curve with drupal, I remember facing it myself - it is climbable though :-)
please let us know if have further questions
Thanks Chris. As I understand, I will need to iterate the $appnode entity looking for a key:value pair.
While I will continue digging, if you have any examples, please send them my way. Thanks again!
It’s not a map, it’s an object so it likely has getters and setters. What field are you after and I’ll see if I can find the right function?
Thanks Chris! This is very helpful when I know the weekend is gearing up 🙂!
The property I need is "something" like $appnode.app_credentials.client_id.
Aha, it would be one of the more complicated fields ;-)
Here, try this, it will create a new array called $credentials
that has all of the application's credentials in it - remember an application can have multiple sets of credentials.
$appCredentials = $appnode->application_credentials_refs->referencedEntities();
if ($appCredentials !== NULL && is_array($appCredentials)) {
foreach ($appCredentials as $cred) {
$credentials[] = [
'client_id' => $cred->client_id(),
'name' => $cred->name(),
'title' => $cred->title(),
'description' => $cred->summary(),
];
}
}
If you're interested in why this code is so complicated, its due to how the data is stored in drupal. Credentials are a separate 'entity' that are cross-referenced to the application for performance reasons, it means we can really exploit the relational database.
The downside is when you want to access the data its a little more complicated - that referencedEntities()
function above tells Drupal to actually expand the xref ID and replace it with the target object rather than having to go do another sql query ourselves. The credentials themselves are then also objects and have getters and setters for each field.
Its never simple :-)
Awesome! I am on holiday today, with the 4th of July on Monday here in the USA, making a long weekend 🙂 so I will get back to you Tuesday at the latest with the outcome.
Is there is documentation somewhere showing the data models along with class diagrams of what you explained above well?
Chris, I have the following in the appcreds_sync_apic_app_delete hook:
$appCredentials = $appnode->application_credentials_refs->referencedEntities();
if ($appCredentials !== NULL && is_array($appCredentials)) {
\Drupal::logger('appcreds_sync')->debug("appCredentials Array size: " . count($appCredentials));
foreach ($appCredentials as $cred) {
$credentials[] = [
'client_id' => $cred->client_id(),
'name' => $cred->name(),
'title' => $cred->title(),
'description' => $cred->summary(),
];
}
}
Looking at the log, the appCredentials array is empty:
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-02 15:24:48: WARNING: [pool www] child 35996 said into stderr: "WATCHDOG: [DEBUG] [appcreds_sync] appCredentials Array size: 0 | user: anonymous ...."
Any other ideas? Thanks again for your help!
It might not be a fully populated node, try this:
$fullNode = Node::load($appnode->id());
$appCredentials = $fullNode->application_credentials_refs->referencedEntities();
if ($appCredentials !== NULL && is_array($appCredentials)) {
\Drupal::logger('appcreds_sync')->debug("appCredentials Array size: " . count($appCredentials));
foreach ($appCredentials as $cred) {
$credentials[] = [
'client_id' => $cred->client_id(),
'name' => $cred->name(),
'title' => $cred->title(),
'description' => $cred->summary(),
];
}
}
You'll need to add use Drupal\node\Entity\Node;
to the top of your file too in order to import the Node class.
This line:
$appCredentials = $fullNode->application_credentials_refs->referencedEntities();
return the following in the log:
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 14:09:41: WARNING: [pool www] child 80194 said into stderr: "WATCHDOG: [ERROR] [php] Error: Call to a member function referencedEntities() on null in appcreds_sync_apic_app_delete() (line 121 of /web/platforms/devportal-9.x-10.0.4-20211201-1711/sites/wsfg.int-dev.apiportal-intdev10.ws.wsfgrp.net/modules/appcreds_sync/appcreds_sync.module) #0 [internal function]: appcreds_sync_apic_app_delete()"
Again, thank you for your help!
that means that fullNode is null - so likely need to work backwards to see why. Fairly hard for me to debug line by line remotely, i dont think thats very efficient!
You'll need to dump stuff to the log (e.g. send it through serialise first so that its a string and then you can see what you're dealing with.) dumping appnode is likely to be too large, but try appnode->id() to check that it has a valid node id, and then go from there.
The $appnode->id() getter call was returning a string of an integer such as 1779.
I used the following:
if (is_string($appnode->nid)) {
$debug = $appnode->nid;
}
else {
$debug = serialize($appnode->nid);
}
\Drupal::logger('appcreds_sync')->debug('%function hook with $appnode->nid: ' . $debug);
To log:
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: "WATCHDOG: [DEBUG] [appcreds_sync] %function hook with $appnode->nid: O:31:"Drupal\Core\Field\FieldItemList":8:{s:7:"*list";a:1:{i:0;O:52:"Drupal\Core\Field\Plugin\Field\FieldType\IntegerItem":8:{s:13:"*definition";O:51:"Drupal\Core\Field\TypedData\FieldItemDataDefinition":2:{s:18:"*fieldDefinition";O:37:"Drupal\Core\Field\BaseFieldDefinition":5:{s:7:"*type";s:7:"integer";s:9:"*schema";N;s:10:"*indexes";a:0:@s:17:"*itemDefinition";r:4;s:13:"*definition";a:6:{s:5:"label";O:48:"Drupal\Core\StringTranslation\TranslatableMarkup":3:{s:9:"*string";s:2:"ID";s:12:"*arguments";a:0:@s:10:"*options";a:0:@}s:9:"read-only";b:1;s:8:"provider";s:4:"node";s:10:"field_name";s:3:"nid";s:11:"entity_type";s:"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: "4:"node";s:6:"bundle";N;}}s:13:"*definition";a:2:{s:4:"type";s:18:"field_item:integer";s:8:"settings";a:6:@s:8:"unsigned";b:1;s:4:"size";s:6:"normal";s:3:"min";s:0:"";s:3:"max";s:0:"";s:6:"prefix";s:0:"";s:6:"suffix";s:0:"";}}s:9:"*values";a:1:@s:5:"value";s:4:"1781";s:13:"*properties";a:0:@s:7:"*name";i:0;s:9:"*parent";r:1;s:14:"*_serviceIds";a:1:@s:16:"typedDataManager";s:18:"typed_data_manager";s:18:"*_entityStorages";a:0:@s:20:"*stringTranslation";N;}}s:11:"*langcode";s:2:"en";s:13:"*definition";r:5;s:7:"*name";s:3:"nid";s:9:"*parent";O:48:"Drupal\Core\Entity\Plugin\DataType\EntityAdapter""
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: ";:8:{s:9:"*entity";O:23:"Drupal\node\Entity\Node":29:{s:10:"in_preview";N;s:9:"*values";a:44:{s:3:"nid";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:4:"1781";}}s:3:"vid";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:4:"1781";}}s:4:"type";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:9:"target_id";s:11:"application";}}s:4:"uuid";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:36:"68ef1fe3-1597-4e2e-9c92-aa020a72d665";}}s:8:"langcode";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:2:"en";}}s:12:"revision_uid";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:9:"target_id";s:1:"9";}}s:18:"revision_timestamp";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"val"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: "ue";s:10:"1657041427";}}s:12:"revision_log";a:1:{s:9:"x-default";a:0:@}s:16:"revision_default";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:1:"1";}}s:17:"isDefaultRevision";a:1:@s:9:"x-default";s:1:"1";s:6:"status";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:1:"1";}}s:3:"uid";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:9:"target_id";s:1:"9";}}s:5:"title";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:12:"Test v10 App";}}s:7:"created";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:10:"1657041427";}}s:7:"changed";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:10:"1657041427";}}s:7:"promote";a:1:{s:9:"x-default""
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: ";a:1:{i:0;a:1:@s:5:"value";s:1:"0";}}s:6:"sticky";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:1:"0";}}s:16:"default_langcode";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:1:"1";}}s:29:"revision_translation_affected";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:1:"1";}}s:26:"content_translation_source";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:3:"und";}}s:28:"content_translation_outdated";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:1:"0";}}s:15:"apic_catalog_id";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:36:"3afac7d8-2274-427b-9dac-a2902d5ec087";}}s:15:"apic_created_at";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:10:"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: ""1657041426";}}s:13:"apic_hostname";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:51:"https://apimgmt-intdev10.ws.wsfgrp.net/consumer-api";}}s:16:"apic_provider_id";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:36:"d7a952bf-4740-4eaf-8473-dbaf8293ff19";}}s:10:"apic_state";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:7:"enabled";}}s:12:"apic_summary";a:1:{s:9:"x-default";a:1:{i:0;a:2:@s:5:"value";s:23:"Testing v10 Module here";s:6:"format";N;}}s:15:"apic_updated_at";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:10:"1657041426";}}s:8:"apic_url";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:92:"/consumer-api/apps/50f1d5cf-4098-40ad-b082-a664bd5f1dbd/68357944-107a-4a66-b2c4"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: "-a10af692e0e3";}}s:23:"application_client_type";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:12:"confidential";}}s:28:"application_consumer_org_url";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:55:"/consumer-api/orgs/50f1d5cf-4098-40ad-b082-a664bd5f1dbd";}}s:28:"application_credentials_refs";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:9:"target_id";s:3:"265";}}s:16:"application_data";a:1:{s:9:"x-default";a:1:{i:0;a:1:{s:5:"value";s:949:"a:15:{s:4:"type";s:3:"app";s:11:"api_version";s:5:"2.0.0";s:2:"id";s:36:"68357944-107a-4a66-b2c4-a10af692e0e3";s:4:"name";s:12:"test-v10-app";s:5:"title";s:12:"Test v10 App";s:7:"summary";s:23:"Testing v10 Module here";s:5:&quo"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: "t;state";s:7:"enabled";s:14:"image_endpoint";s:101:"https://wsfg.int-dev.apiportal-intdev10.ws.wsfgrp.net/wsfg/int-dev/modules/apic_app/images/app_15.png";s:15:"lifecycle_state";s:10:"production";s:10:"created_at";s:24:"2022-07-05T17:17:06.739Z";s:10:"updated_at";s:24:"2022-07-05T17:17:06.739Z";s:7:"org_url";s:55:"/consumer-api/orgs/50f1d5cf-4098-40ad-b082-a664bd5f1dbd";s:3:"url";s:92:"/consumer-api/apps/50f1d5cf-4098-40ad-b082-a664bd5f1dbd/68357944-107a-4a66-b2c4-a10af692e0e3";s:19:"app_credential_urls";a:1:@i:0;s:141:"/consumer-api/apps/50f1d5cf-4098-40ad-b082-a664bd5f1dbd/68357944-107a-4a66-b2c4-a10af692e0e3/credentials/2b4affa1-3a64-47bb-b09b-116aee56bd4f";s:9:"client_id";s:32:"e0554a207faf63c1abd8dc4fe6d0ea66";}";}}}s:19:"application_enabled";a"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: ":1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:4:"true";}}s:14:"application_id";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:36:"68357944-107a-4a66-b2c4-a10af692e0e3";}}s:27:"application_lifecycle_state";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:10:"PRODUCTION";}}s:16:"application_name";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:5:"value";s:12:"test-v10-app";}}s:7:"metatag";a:1:{s:9:"x-default";a:0:@}s:4:"path";a:1:{s:9:"x-default";a:1:{i:0;a:1:@s:8:"langcode";s:2:"en";}}s:9:"menu_link";a:1:{s:9:"x-default";a:0:@}s:17:"application_image";a:1:{s:9:"x-default";a:0:@}s:29:"application_lifecycle_pending";a:1:{s:9:"x-default";a:0:@}s:30:"application_redirect_endpoi"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: "nts";a:1:{s:9:"x-default";a:0:@}s:29:"application_subscription_refs";a:1:{s:9:"x-default";a:0:@}}s:9:"*fields";a:0:@s:19:"*fieldDefinitions";N;s:12:"*languages";N;s:14:"*langcodeKey";s:8:"langcode";s:21:"*defaultLangcodeKey";s:16:"default_langcode";s:17:"*activeLangcode";s:9:"x-default";s:18:"*defaultLangcode";s:2:"en";s:15:"*translations";a:1:{s:9:"x-default";a:1:@s:6:"status";i:1;}s:24:"*translationInitialize";b:0;s:14:"*newRevision";b:0;s:20:"*isDefaultRevision";s:1:"1";s:13:"*entityKeys";a:4:@s:6:"bundle";s:11:"application";s:2:"id";s:4:"1781";s:8:"revision";s:4:"1781";s:4:"uuid";s:36:"68ef1fe3-1597-4e2e-9c92-aa020a72d665";s:25:&quo"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: "t;*translatableEntityKeys";a:8:{s:5:"label";a:1:@s:9:"x-default";s:12:"Test v10 App";s:8:"langcode";a:1:@s:9:"x-default";s:2:"en";s:6:"status";a:1:@s:9:"x-default";s:1:"1";s:9:"published";a:1:@s:9:"x-default";s:1:"1";s:3:"uid";a:1:@s:9:"x-default";s:1:"9";s:5:"owner";a:1:@s:9:"x-default";s:1:"9";s:16:"default_langcode";a:1:@s:9:"x-default";s:1:"1";s:29:"revision_translation_affected";a:1:@s:9:"x-default";s:1:"1";}s:12:"*validated";b:0;s:21:"*validationRequired";b:0;s:19:"*loadedRevisionId";s:4:"1781";s:33:"*revisionTranslationAffectedKey";s:29:"revision_translation_affected";s:37:"*enforceRevisionTranslationAffected";a:0:@s:15"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: ":"*entityTypeId";s:4:"node";s:15:"*enforceIsNew";N;s:12:"*typedData";N;s:16:"*cacheContexts";a:0:@s:12:"*cacheTags";a:0:@s:14:"*cacheMaxAge";i:-1;s:14:"*_serviceIds";a:0:@s:18:"*_entityStorages";a:0:@s:12:"*isSyncing";b:0;}s:13:"*definition";O:49:"Drupal\Core\Entity\TypedData\EntityDataDefinition":1:{s:13:"*definition";a:1:{s:11:"constraints";a:2:{s:10:"EntityType";s:4:"node";s:6:"Bundle";a:1:@i:0;s:11:"application";}}}s:7:"*name";N;s:9:"*parent";N;s:14:"*_serviceIds";a:0:@s:18:"*_entityStorages";a:0:@s:20:"*stringTranslation";N;s:19:"*typedDataManager";N;}s:14:"*_serviceIds";a:1:@s:16:"typedDataManager";s:18:"typed_data_manager";s:18:"*_entityStorages";a:0:@s:"
[ nginx stdout] 587 80eab5:08cd01:a86b32 2022-07-05 17:17:12: "10.131.77.205, 10.131.171.35" apiportal-intdev10.ws.wsfgrp.net "POST /wsfg/int-dev/application/68357944-107a-4a66-b2c4-a10af692e0e3/delete HTTP/1.1" 303 518 1322 1324 "https://apiportal-intdev10.ws.wsfgrp.net/wsfg/int-dev/application/68357944-107a-4a66-b2c4-a10af692e0e3/delete" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" 0.802 "-"
[ php-fpm stderr] 588 80eab5:08cd01:af4a9d 2022-07-05 17:17:12: WARNING: [pool www] child 1330 said into stderr: "20:"*stringTranslation";N;} | user: anonymous | uri: https://wsfg.int-dev.apiportal-intdev10.ws.wsfgrp.net/wsfg/int-dev/application/68357944-107a-4a66-b2c4-a10af692e0e3/delete | referer: https://apiportal-intdev10.ws.wsfgrp.net/wsfg/int-dev/application/68357944-107a-4a66-b2c4-a10af692e0e3/delete
"
I see the client_id
key and the value of e0554a207faf63c1abd8dc4fe6d0ea66
.
Other than manually rebuilding the $appnode->nid log output into an actual hierarchy, what is the notation for the client_id value in the $appnode->nid object?
Just wanting to follow up on this topic. Any ideas? Thanks in advance as I know you are all busy.
With Anu's help from IBM Support, here is what I did to get the client ID when a Portal Application is deleted.
First, instead of using the
if (isset($data['application_credentials_refs'])) {
foreach ($data['application_credentials_refs'] as $ref) {
$cred = ApplicationCredentials::load($ref);
if ($cred !== NULL) {
$credentials[] = [
'client_id' => $cred->client_id(),
];}
}
}
I then do the following to get the client Id out of the array:
$clientId = $credentials[0]['client_id'];
Of course, this is an issue when the application has multiple creds, but this worked.
Thanks again for the help!
I am attempting to get values out of the $appnode input parameter within an apic_app_delete($appnode, $data) hook. I see where it is logged:
However, when attempting to determine the datatype of the $appnode:
The following is in the log:
Also, when attempting:
The following is in the log:
I understand that this is more of a PHP issue, however, I am trying to use the $appnode param and am stumped. Thanks!