function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
hemmhemm 

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.

 

 

Lawrence-CECLawrence-CEC

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

 

hemmhemm

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?

Park Walker (TAGL)Park Walker (TAGL)

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 

Park Walker (TAGL)Park Walker (TAGL)

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 

SuperfellSuperfell
You can go upto 5 levels for parent relationships (and 1 level down for aggregate children)
Park Walker (TAGL)Park Walker (TAGL)

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 

pokpokpalayokpokpokpalayok

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?

t14t14

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;

.....

 

Message Edited by t14 on 01-13-2010 02:23 AM