You need to sign in to do that
Don't have an account?
PHP Function to retrieve values of relationship fields
Ever since relationship fields came out, I've always had a hard time getting values from them in a SOQL query. I've been able to write a reliable function to retrieve values for fields on the main object or in a relationship one level deep, but my function falls down (does not scale) when looking relationships further away.
For example, the query select id, status, lead.company, contact.account.name from CampaignMember limit 5, I am able to grab Status off CampaignMember and Lead.Company, but my function has trouble getting contact.account.name.
Bottom line is that I wanted to ask the community if they've written a "get a value from an sObject" function that is capable of hanlding relationship fields no matter how many objects away they are.
Do you mean something other than explictly traversing the results tree? I.e. something other than:
$response->records[0]->fields->Lead->fields->Company
(or somesuch... I'd be surprised if I got that right! :) )
Or are you looking for that syntax to get to contact.account.name?
-L
If it worked similar to your example, that'd be nice, but it's not setup that way today. Basically, if there are relationship fields, they all contained within $sObject->sobjects. The sObjects are only there if relationship fields exist.
I would love it if someone smarter than me wrote a function similar to doing $sObject = new SObject($record);, where the result was a flattened out "fields" grouping where the following would all work.
$sObject->fields->Name;
$sObject->fields->Account.Name;
$sObject->fields->Account.Owner.LastName;
$sObject->fields->CreatedBy.Alias;
Basically, a function that would process the sObject, run through all those sobjects that are there for relationship fields and put all fields under the fields section of an sObject.
Make sense?
It seems like you are looking for something that will take a query like:
Select c.MailingState, c.MailingCity, c.LastName, c.Id, c.FirstName,
c.Account.BillingState, c.Account.BillingCity, c.Account.Name,
c.Account.Id, c.AccountId,
(Select Id, Subject, Status From Tasks) From Contact c
Where c.Account.Name = '$account'
and do something like this with the results:
$list = unpackSObjects($queryResult);
//print_r($list);
foreach ($list as $cont) {
print 'Contact: ' . $cont->FirstName . ' ' . $cont->LastName . "<br />\r\n";
print 'Account: ' . $cont->Account->Name . "<br />\r\n";
// check to see if there are any tasks
if (is_object($cont->Tasks))
{
print "Tasks: <br />\r\n";
foreach($cont->Tasks as $task) {
print "----> " . $task->Id . ' ' . $task->Subject . ' (' . $task->Status . " ) <br />\r\n";
}
} else {
print "No Tasks<br />\r\n";
}
print "------------------------<br />\r\n";
}
and get the following:
Contact: Oscar Meyer
Account: Microarts
No Tasks
------------------------
Contact: Jones Bob
Account: Microarts
No Tasks
------------------------
Contact: Jessica Rabbit
Account: Microarts
No Tasks
------------------------
Contact: Stephanie Ketchum
Account: Microarts
Tasks:
----> 00T4000000mPLFxEAO Take a break (Not Started)
------------------------
If I've got this right then you may want to take a look at the code at http://shared.redsummit.com/sforce/unpackSObjects.zip.
Note that parent objects are directly accessible (Account->Name) while child objects are in an array (Tasks[0]->Subject). This seemed like a reasonable way to handle the two situations. The routine is recursive, so it should work with queries of any reasonable depth, but it has not been tested in any serious manner.
Park
It's not clear that you can navigate to a third level using relationship queries. The query that you pose does not return the account name in PHP nor in Eclipse. Have you seen a situation where this will work?
Park
Simon,
Thanks for the clarification.
Hemm,
It's hard to come up with an example of more than three levels up in the standard development account. I can confirm that the code referenced above will work with this query:
Select c.Contact.FirstName, c.Contact.LastName, c.ContactId, c.Contact.Account.Name, c.Campaign.Type, c.Campaign.Name, c.CampaignId, c.FirstRespondedDate From CampaignMember c
... allowing you to reference Result[0]->Contact->Account->Name as well as all the other fields returned.
Park
Thanks for these guys very helpful..but how do you suggest the better approach to retrieve these
Select a.AccountNumber, a.BillingCity, a.BillingCountry, a.BillingPostalCode, a.BillingState, a.BillingStreet, a.Id, a.Name, Owner.Name , CreatedBy.Name , LastModifiedby.Name from Account a
here's my output:
Array ( [0] => SObject Object ( [type] => Account [fields] => stdClass Object ( [Name] => United Oil & Gas Corp. [AccountNumber] => CD355118 [BillingCity] => New York [BillingCountry] => [BillingPostalCode] => [BillingState] => NY [BillingStreet] => 1301 Avenue of the Americas New York, NY 10019 USA [1] => SObject Object ( [type] => User [fields] => stdClass Object ( [LastName] => sarquilla [FirstName] => pablito ) ) [3] => SObject Object ( [type] => User [fields] => stdClass Object ( [Name] => pablito sarquilla ) ) [4] => SObject Object ( [type] => User [fields] => stdClass Object ( [Name] => pablito sarquilla ) ) ) [Id] => 001A0000002QNHTIA4 ) )
As you can see I can no longer distinguish which came from owner, created and lastmodifiedby. I'm not sure if alias is supported in SOQL coz I can't find any instruction on how-to.
Any ideas?
Hi
Maybe try somthing like this.
for the id fields
$record->fields->Id
$record->fields->{0}->Id
$record->fields->{1}->Id
$record->fields->{2}->Id
.....
and for the other fields try this
$record->fields->Name
$record->fields->{0}->fields->Name;
.....