+ Start a Discussion
msimondsmsimonds 

How to access APEX classes

I am new to APEX classes and have a few questions.  I posted once in the PHP forums to try and find a solution, but the answers were not clear

1)  If I create an APEX class can I access this from an external server/system or set of scripts that I write?  The script can be written in any language: PHP, Perl, etc....
2) Once I create the class and generate the WSDL from the class, do I download it and then use this like I do the Partner WSDL file


Any help or guidance would be appreciated.

I hope this is not too generic to answer my questions

Thanks,
Mike
sfdcfoxsfdcfox
If you use the webservice keyword, you can use the function as a webservice call from your custom <PHP, .NET, Java, etc> code. You can download the WSDL for it and use it just like the Partner or Enterprise WSDL files. Of course, you still need to login() or somehow otherwise obtain a session ID before you attempt to call the service.
sfdcfoxsfdcfox
As an addendum, the login()call isn't in the WSDL for the Apex class, so you still have to download a second WSDL, such as the Enterprise WSDL to obtain the session ID. The exception is if you're calling this class in response to an Outbound Message, which can include the session ID in the notification, but then you'd still be using two WSDL files (one for the webservice, one for the outbound message notification).
msimondsmsimonds
Thanks sfdcfox,

I will give that a try, I appreciate the guidance

~Mike
ClintClint
I'm new to salesforce (first post, first day developing for it) and I've been having a bit of a problem with this myself.

Another developer we're working with has developed some Apex classes as webServices. I've downloaded the php toolkit and the wsdl, and tried to access a simple method called "subscribe", which gave me a "INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session" error.

Looking about a bit I discovered it was necessary to get a session id first, which I am able to do via the partner wsdl and the "login" method. I then tried setting the sessionId for a new connection via a setSessionHeader call, but when I try and call the "subscribe" method again, I get the same invalid session error.

I am posting a bit of code to illustrate what I'm referring to below.

Code:
$mySforceConnection = new SforcePartnerClient();
$mySoapClient = $mySforceConnection->createConnection("includes/salesforce/soapclient/partner.wsdl.xml");
$mylogin = $mySforceConnection->login("username", "passandtoken");

$mySforceConnection2 = new SforcePartnerClient();
$mySoapClient2 = $mySforceConnection2->createConnection("includes/salesforce/integration.wsdl");
$mySforceConnection2->setSessionHeader($mylogin->sessionId);

Any tips, pointers or help would be greatly appreciated... thanks!
 

ClintClint
Well, a bit of *cough* progress on this.

In trying to use a generic PHP5 SoapClient instead of a SforcePartner client, I'm no longer getting the "Invalid Session ID" message, and am now getting an "Element {}item invalid at this location" error.

It occurs to me that this could be because I'm not even getting to the point where the session id can be judged invalid, however with such a non-specific error message it's hard for me to tell at this point.

Code:
  $mySforceConnection = new SforcePartnerClient();
  $mySoapClient = $mySforceConnection->createConnection("includes/salesforce/soapclient/partner.wsdl.xml");
  $mylogin = $mySforceConnection->login("username", "passandtoken");
  
  $client = new SoapClient("includes/salesforce/integration.wsdl");
  $client->__setSoapHeaders(array(new SoapHeader("urn:partner.soap.sforce.com", "SessionHeader", array("sessionId" => $mylogin->sessionId))));
  $client->subscribe(array("email" => "email@domain.com", "firstName" => "Fname", "lastName" => "Lname"));

 I've also tried the lower level SoapCall function, which returns the same error unfortunately

Code:
$client->__soapCall("subscribe", array("email" => "email@domain.com", "firstName" => "Fname", "lastName" => "Lname"), null, new SoapHeader("urn:partner.soap.sforce.com", "SessionHeader", array("sessionId" => $mylogin->sessionId)));

 As always, any tips, pointers, etc. are appreciated!


ClintClint
Okay, after some further fiddling with the php classes based on this thread: http://community.salesforce.com/sforce/board/message?board.id=PerlDevelopment&thread.id=1582&view=by_date_ascending&page=1

Code:
$mySforceConnection = new SforcePartnerClient();
$mySoapClient = $mySforceConnection->createConnection("includes/salesforce/soapclient/partner.wsdl.xml");
$mylogin = $mySforceConnection->login("username", "passandtoken");

$client = new SoapClient("includes/salesforce/integration.wsdl");

$sforce_header = new SoapHeader("urn:partner.soap.sforce.com", "SessionHeader", array("sessionId" => $loginResult->sessionId));
$batch_size = new QueryOptions(25);
$query_header = new SoapHeader("urn:partner.soap.sforce.com","QueryOptions", $batch_size);
$assign = new AssignmentRuleHeader(null, true);
$rule_header = new SoapHeader("urn:partner.soap.sforce.com","AssignmentRuleHeader", $assign);
$client->__setSoapHeaders(array($sforce_header, $query_header, $rule_header));

$client->subscribe(array("email" => "email@domain.com", "firstName" => "Fname", "lastName" => "Lname"));

 And I'm back to "INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session"

SuperfellSuperfell
The namespace your setting on the sessionHeader is wrong, so the server is ignoring it, and hence saying that there's no valid session.

You can get the correct namespace from your integration.wsdl (look at the targetNamespace attribute of the schema element)
ClintClint
Hi Simon!
First off thanks for the help!

I tried what you suggested, as shown below...

Code:
$mySforceConnection = new SforcePartnerClient();
$mySoapClient = $mySforceConnection->createConnection("includes/salesforce/soapclient/partner.wsdl.xml");
$mylogin = $mySforceConnection->login("username", "passandtoken");

$client = new SoapClient(APPLICATION_FILEROOT."includes/salesforce/integration.wsdl");
$sforce_header = new SoapHeader("http://soap.sforce.com/schemas/class/WebsiteIntegrationService", "SessionHeader", array("sessionId" => $loginResult->sessionId));
$client->__setSoapHeaders(array($sforce_header));

$client->subscribe(array("email" => "email@domain.com", "firstName" => "Fname", "lastName" => "Lname"));

 ...however, I'm still getting the INVALID_SESSION_ID error. Any other ideas on what might be causing it?

Thanks again!

Clint

ClintClint
Nevermind, found it!

As a result of multiple changes to my code I was using $loginResult->sessionId instead of $mylogin->sessionId, which was, of course, null.

Once I set it to the correct value with the new namespace it worked straight off.

Thanks again Simon, you're a prince among developers! :smileyhappy:
msimondsmsimonds
So Clint you were able to do this:

  1. Create an APEX class in your instance of salesforce
  2. Generate and download a WSDL file for this class
  3. Then use this class via the PHP toolkit?


Can you post an example?  That would be EXTREMELY helpful, if you do not mind, I would truly appreciate it


~Mike

ClintClint
Hi Mike,
Well, the Apex class method I'm connecting to appears to be a stub at the moment, so it's hard to tell if I'm calling it 100% correctly. I'm not developing the Salesforce end of it, my responsibility at this point is to push subscriber data in. But at this point yes, I am able to connect via the partner wsdl and call the method via SOAP without raising an error.

The relevant portions of the Apex code seem to be:

Code:
global class WebsiteIntegrationService {
 global class Subscriber {
  webService String firstName;
  webService String lastName;
  webService String email;
 }
  
 webService static void subscribe(Subscriber sub) {
  
 }
}

My php test code looks as follows:

Code:
require_once("salesforce/soapclient/SforcePartnerClient.php");

try {  
 $mySforceConnection = new SforcePartnerClient();
 $mySoapClient = $mySforceConnection->createConnection("soapclient/partner.wsdl.xml");
 $mylogin = $mySforceConnection->login("username", "passandtoken");
 
 $client = new SoapClient("integration.wsdl");
 $sforce_header = new SoapHeader("http://soap.sforce.com/schemas/class/WebsiteIntegrationService", "SessionHeader", array("sessionId" => $mylogin->sessionId));
 $client->__setSoapHeaders(array($sforce_header));
 $r = $client->subscribe(array("email" => "email@domain.com", "firstName" => "Fname", "lastName" => "Lname"));
} catch (Exception $e) {
 echo $e->faultstring;
}

So what I'm doing is basically connecting to the partner wsdl via the SforcePartnerClient and logging in via the login method, which returns, among other things, a session id.

I then instantiate a php SoapClient and SoapHeader. The key part of solving the problem that I was having (thanks again, Simon!) was to set the namespace of the SoapHeader to the value specified by the targetNamespace attribute of the xsd:schema node. Then just set the name of the SoapHeader to "SessionHeader" with a value of an array with the name/value pair of "sessionId"/$mylogin->sessionId (or the "sessionId" portion of the value returned from the partner wsdl login call).

There may be further bumps in the road here as the subscribe function is fleshed out, of course (as I mentioned, I'm very new to Salesforce), but for now I can connect and call the function with no errors raised.

Clint

ClintClint
Just a quick addendum to this thread. It turns out that the correct way to call the subscribe web service is:

Code:
$subscriber = array(
 "sub" => array(
  "email" => "email@domain.com",
  "firstName" => "Fname",
  "lastName" => "Lname"
 )
);
  
$r = $client->subscribe($subscriber);

 

msimondsmsimonds
Thanks for that Clint

Listen this may sound stupid and forgive me for that

Can you try and explain what you are doing calling the Service?  I have done a lot of integration with Salesforce using PHP, but never really figured out what would be a good reason to use PHP to connect to an APEX class?

I am just trying to get some ideas


~Mike
ClintClint
Sure Mike!

Well, in our case we've been working with an existing client for years and have developed a website for them that contains newsletter subscriptions, speaking and consulting requests, targeted mini-sites withing the main sites for certain groups that collect various bits of information, and a store.

A couple of months ago they decided they wanted to transition to a centralized place to aggregate all this information and after a bit of research they ultimately went with salesforce.

In the case of the subscribe method detailed above, we're basically creating a contact in salesforce when someone signs up for their newsletter.

Next up we'll be pushing in data from various points in the store: when a purchase is made, when a purchase order is initially entered and later when it's approved or denied, when a customer adds an address, changes an existing address, etc.

That's pretty much the scope of what we're doing so far :smileyhappy:

Clint
msimondsmsimonds
Thanks for that Clint

So basically it seems to me that you are just capturing data and inserting it into salesforce as a contact via this web service?  Hmmmm  sounds interesting

So your script is handing off this data to another APEX process, I like it

BUT I am not sure I would use a web service for this or even deem it necessary.  Why not just create a contact straight in to Salesforce without using an APEX class
Is it faster to do it this way? 

I guess that is where I am confused, but your example has really opened the door for me to try new things, and again, thanks for the example
ClintClint
We've actually approached it in a couple of different ways. The straight form posts, such as the speaking and consulting forms, do call salesforce directly. Some of the custom mini-sites create a contact via a specially formatted email that gets sent in to salesforce.

The reason for using a web service probably started initially with the store. There's a lot going on there code-wise, so I think the decision was taken at some point that putting in a quick webservice call in the middle of the existing code in order to have the data pushed to salesforce.

Same with the newsletter. We're populating an existing suite that we use for mass mailings with the data, so I think it made sense to just insert a quick webservice call.

Ultimately though, I'm merely the implementer here, as our client hired a salesforce guy, so from my end it was "here's the wsdl, now make it go!"

Clint
msimondsmsimonds
Thanks Clint for responding to all my topics, I really appreciate it!


~Mike
TLFTLF

Hi. I just wanted to relate my experience on this topic, as it took me quite awhile to get this working right for even the most simple web service method. I had the following Apex web service method:

Code:
global class Test {

    webService static String greetUser(String greeting) {
        return greeting + ' ' + UserInfo.getUserName();
    }
}

 Not exactly complicated. I wanted to call this from a PHP script using PHP 5.
 
The first problem that I encountered was that PHP did not seem to be picking up changes in my WSDL file. As it turns out, PHP 5 has WSDL caching for performance reasons. If you are going to be changing your WSDL file during development you should turn this off by setting the property "soap.wsdl_cache_enabled" to 0 in your php.ini file.
Then I tried calling my web service from a PHP script that looked like this:
 
Code:
    $mySforceConnection = new SforcePartnerClient();
    $mySforceConnection->createConnection('partner.wsdl.xml');
    $loginResult = $mySforceConnection->login('myusername', 'mypasswordandsecuritytoken');
    $userInfo = $mySforceConnection->getUserInfo();
    print_r("Login successful. User info: ".$userInfo->userName."\n");
         
    print_r("Calling custom APEX webservice method.\n");
    $client = new SoapClient('Test.wsdl.xml', array("trace" => 1, "exceptions" => 0));    
    $sforce_header = new SoapHeader('http://soap.sforce.com/schemas/class/Test', 
        'SessionHeader', array('sessionId' => $loginResult->sessionId));
    $client->__setSoapHeaders(array($sforce_header));
    $client->greetUser("Hey you");

Alas, this did not work. It seems like the string "Hey you" was not being passed properly. After much searching and experimenting I found some tips and figured out that I have to invoke the web service method as follows (the following three lines replace the $client->greetUser("Hey you") call above):

 
Code:
    $parameters->greeting = "Hey you";
    $response = $client->__soapCall("greetUser", array("greetUser" => $parameters));
    $response = $client->greetUser($parameters);

 
Maybe this is obvious to more experienced PHP developers, but I could not find any one good document or example that explains how to do this, either in Salesforce's documentation or in PHP documentation. Hopefully this simple example saves someone a lot of grief.
Ron WildRon Wild
Sorry to beat this post to death ... but I've copied the code from earlier posts, checked and rechecked for errors .... and I'm still getting an invalid session id error.

I'm getting a session id from the login call without any problem.  The namespace is straight out of the generated WSDL file.  The only thing I can see that might be different is that my Apex class is managed - could that be causing the error?

Code:
try {
 
     $mySforceConnection = new SforcePartnerClient();
     $mySforceConnection->createConnection(SF_WSDL);
     $loginResult = $mySforceConnection->login(SF_USERNAME, SF_PASSWORD);    
 $sessionId = $loginResult->sessionId;
 
 Logger::trace('Login Server URL='.$loginResult->serverUrl.' Session ID ='.$sessionId);
 $client = new SoapClient(COSMIC_WSDL);
 $sforce_header = new SoapHeader("http://soap.sforce.com/schemas/class/ptl/Portal", 
       "SessionHeader", 
       array("sessionId" => $sessionId ) );
 $client->__setSoapHeaders(array($sforce_header));
 $parameters->contactId = $this->sfid;
 $parameters->notes = "It worked";
 $r = $client->logPortalLogin($parameters);

} catch (Exception $ee) {
 Logger::logError($ee, 'Error logging portal login (contact Id: '.$this->sfid.').');
 return false;
} 

 

TLFTLF
Is your partner WSDL file (SF_WSDL) current, or could it be outdated? I suggest trying to generate a fresh copy from Setup | Develop | API | Download Partner WSDL if you haven't already.
msimondsmsimonds
@ TLF

Maybe I am a little lost when it comes to "why would you want to access an APEX class from PHP"

I know that you were just running a test,  but are you greeting the user in an application  on your server?  Or in Salesforce?

What was the purpose of the test.  Why would you want to be able to access the Class

I am just understanding why you would want to do this, just trying to get a clearer picture on why it would be important since APEX is really used within Salesforce for performing needs within your instance

Sorry for sounding stupid, just trying to see if I could somehow use this within our applications


Thanks,
Mike
msimondsmsimonds
So I tested your code for the test class

Code:
global class Test {

    webService static String greetUser(String greeting) {
        return greeting + ' ' + UserInfo.getName();
    }
}


and used the following php (just like yours)



Code:
<—php
require_once ('./soapclient/SforcePartnerClient.php');

$mySforceConnection = new SforcePartnerClient();
$mySforceConnection->createConnection('./includes/partner.wsdl.xml');
$loginResult = $mySforceConnection->login('username','password');
$userInfo = $mySforceConnection->getUserInfo();
print_r("Login successful. User info: ".$userInfo->userName."\n");

print_r("Calling custom APEX webservice method.\n");
$client = new SoapClient('./includes/test.wsdl.xml',array("trace" => 1,"exceptions" => 0));
$sforce_header = new SoapHeader('http://soap.sforce.com/schemas/class/Test','SessionHeader',array('sessionId' => $loginResult->sessionId));
$client->__setSoapHeaders(array($sforce_header));

$parameters->greeting = "Hey you";
$response = $client->__soapCall("greetUser",array("greetUser" => $parameters));
$response = $client->greetUser($parameters);

echo '<pre>'.print_r($response,true).'</pre>';

–>

 


Again, why wouldn't you just use a SOQL statement to get the same information?

Sorry to make this thread bleed even more!

~Mike


Message Edited by msimonds on 08-19-2008 09:13 AM
TLFTLF
My requirement, ultimately, is to be able to create an object in Salesforce, from a PHP web application. I wanted to be able to perform some custom business logic first (implemented in the server-side APEX method), before the object is created. Basically, I'm trying to do something similar to web-to-lead functionality, but web-to-lead didn't quite suit my needs. Hope this helps.
TLFTLF
My requirement, ultimately, is to be able to create an object in Salesforce, from a PHP web application. I wanted to be able to perform some custom business logic first (implemented in the server-side APEX method), before the object is created. Basically, I'm trying to do something similar to web-to-lead functionality, but web-to-lead didn't quite suit my needs. Hope this helps.
msimondsmsimonds

TLF wrote:
My requirement, ultimately, is to be able to create an object in Salesforce, from a PHP web application. I wanted to be able to perform some custom business logic first (implemented in the server-side APEX method), before the object is created. Basically, I'm trying to do something similar to web-to-lead functionality, but web-to-lead didn't quite suit my needs. Hope this helps.


That makes some sense to me and thank  you for replying to my post. 

So all your business logic/checks will be handled in the APEX class by passing it the web to lead information via the API

I get it and that does make it a little more clearer

~Mike
SuperfellSuperfell
There's 2 main reasons to use apex web services.

1. encapsulate data requests that would otherwise require multiple queries or roundtrips. for distributed computing round trips are evil, if you have an integration where you need multiple pieces of data, and/or you need to perform additional computation on that data, you can write this in apex and expose it as a web service so that your integration only needs to make one round trip. (this is particularly useful if for example you need to query 100 rows to calculate 2 or 3 values, you can do the calculation near the data, and just ship the small results over the WAN).

2. control transaction boundaries. the enterprise or partner APIs only allow you to insert/update data of a single type in a single transaction, this makes integrations into more complex data models much more complex, for example if you're trying to integrate opportunities, then you might want to create opportunities, line items, contact roles etc all in a single transaction to make error recovery much simpler. In the regular API, this requires you to build compensating actions for failures (e.g. insert opportunity, insert line items, insert contact roles, if the last fails, you may need to go back and delete the opportunity). By moving these multi-type inserts into apex, you can create these complex object hierarchies in a single transaction, and simplify your integrations error handling.
msimondsmsimonds

SimonF wrote:
There's 2 main reasons to use apex web services.

1. encapsulate data requests that would otherwise require multiple queries or roundtrips. for distributed computing round trips are evil, if you have an integration where you need multiple pieces of data, and/or you need to perform additional computation on that data, you can write this in apex and expose it as a web service so that your integration only needs to make one round trip. (this is particularly useful if for example you need to query 100 rows to calculate 2 or 3 values, you can do the calculation near the data, and just ship the small results over the WAN).


Thanks for the clarification Simon, I do appreciate it

So we have this process currently using PHP to create a new record in a custom object.

1) a work flow kicks off am outbound message with 10 fields on the SOAP message when a status is changed to "Won"

2) We take that inbound message from Salesforce and process it, we query 4 standard objects to get data we need via the API

3) we use this data to create a new record on the new custom object

In this case, we could build this right into Salesforce using APEX, am I correct? 

If this is the case, we would not need to access a web service via the API, am I correct?



Our process works perfectly, but I was looking into using APEX for future items such as this.

I appreciate your help

~Mike
SuperfellSuperfell
You could wrap steps 2 and 3 in an apex web service (depending on how much data step 2 has to query), but if this process doesn't use any external data, you could likely just re-write the whole thing as an apex trigger.
Ron WildRon Wild
Updating the Partner WSDL did the trick ... apparently I had overwritten the current version when I upgraded to the latest PHP toolkit.  

For anyone else who might be struggling with this error,  I did have to remove the cached wsdl file from my server.  Often this is stored in your /tmp directory.

Thanks for the suggestion!




msimondsmsimonds

Ron Wild wrote:
Updating the Partner WSDL did the trick ... apparently I had overwritten the current version when I upgraded to the latest PHP toolkit.  

For anyone else who might be struggling with this error,  I did have to remove the cached wsdl file from my server.  Often this is stored in your /tmp directory.

Thanks for the suggestion!






Ron

At the top of all my scripts integrating with Salesforce I place the following code:

Code:
ini_set("soap.wsdl_cache_enabled","0");


that way I do not have any cache problems


~Mike


PS:  Thanks Simon I appreciate it!
 



Message Edited by msimonds on 08-19-2008 11:15 AM
hemmhemm
Clint, this is the best/only working example I have seen of calling an Apex Web Service from PHP.  Thanks!

Using your example, I have it working where I can call the Web Service as along as I don't pass any parameters in.  When I try passing parameters in, I get an error that says "System.NullPointerException: Attempt to de-reference a null object Class.WebsiteIntegrationService.subscribe: line 11, column 23"

Here's a copy of my Apex Class I am using right now.
Code:
global class WebsiteIntegrationService {

 global class Subscriber {
   webService String firstName;
   webService String lastName;
   webService String email;
  }
   
  webService static void subscribe(Subscriber sub) {
   Lead l = new Lead();
   l.firstname = sub.firstName;
   l.lastname = sub.lastName;
   l.company = 'ABC Company';
   l.email = sub.email;
   insert l;
  }

}

 My PHP looks exactly like what you have in your post on this thread except I connect to my Org, obviously.  Am I referencing the field sub.firstName incorrectly or passing it in incorrectly?  PHP below:

Code:
// Turn off WSDL caching
ini_set("soap.wsdl_cache_enabled", "0");
define ("_WSDL_", 'salesforceAPI/partner_11_1.wsdl.xml');

require_once("salesforceAPI/SforcePartnerClient.php");
require_once('salesforceAPI/SforceHeaderOptions.php');

try { 
 $mySforceConnection = new SforcePartnerClient();
 $mySoapClient = $mySforceConnection->createConnection(_WSDL_);
 $mylogin = $mySforceConnection->login("user", "passandtoken");
 
 $client = new SoapClient("WebsiteIntegrationService.wsdl");
 $sforce_header = new SoapHeader("http://soap.sforce.com/schemas/class/WebsiteIntegrationService", "SessionHeader", array("sessionId" => $mylogin->sessionId));
 $client->__setSoapHeaders(array($sforce_header));
 $r = $client->subscribe(array("email" => "email@domain.com", "firstName" => "Fname", "lastName" => "Lname"));
 
} catch (Exception $e) {
 echo $e->faultstring;
}

 



ClintClint
Hey hemm!

The null pointer exception sounds like the arguments aren't getting passed in right. Try calling your subscribe method like so and see if it works any better.

Code:
$subscriber = array(
 "sub" => array(
  "email" => "email@domain.com",
  "firstName" => "Fname",
  "lastName" => "Lname"
 )
);

$r = $client->subscribe($subscriber);

 

hemmhemm
you are a genius.  that worked!
Ron WildRon Wild
The php code you posted is for a call to a webservice defined as follows:

Code:
global class WebsiteIntegrationService {

  
  webService static void subscribe(String email, String firstName, String lastName) {
   Lead l = new Lead();
   l.firstname = sub.firstName;
   l.lastname = sub.lastName;
   l.company = 'ABC Company';
   l.email = sub.email;
   insert l;
  }

}

 Off the top of my head I don't know the exact syntax, but I think you need to put the parms in a std object before passing them in as an array, or you might need to pass them in as an array in an array.





ClintClint

hemm wrote:
that worked!



Sweet! :smileyhappy:

hemmhemm
My final code.  I cleaned it up a bit to make it more readable for you all.  The array in an array thing can be a bit confusing.  Also, the need to match the array index name with the variable name in Apex can be confusing.

Code:
// Turn off WSDL caching
ini_set("soap.wsdl_cache_enabled", "0");
define ("_WSDL_", 'salesforceAPI/partner_11_1.wsdl.xml');

require_once("salesforceAPI/SforcePartnerClient.php");
require_once('salesforceAPI/SforceHeaderOptions.php'); // Salesforce Adapter - Header options

try { 
 $mySforceConnection = new SforcePartnerClient();
 $mySoapClient = $mySforceConnection->createConnection(_WSDL_);
 $mylogin = $mySforceConnection->login("user", "passandtoken");
 
 $client = new SoapClient("WebsiteIntegrationService.wsdl");
 $sforce_header = new SoapHeader("http://soap.sforce.com/schemas/class/WebsiteIntegrationService", "SessionHeader", array("sessionId" => $mylogin->sessionId));
 $client->__setSoapHeaders(array($sforce_header));
 $SubscriberArray = array();
  $wrkArray = array();
  $wrkArray["firstName"] = "FName";
  $wrkArray["lastName"] = "LName";
  $wrkArray["email"] = "email@domain.com";
 $SubscriberArray["sub"] = $wrkArray;

 $r = $client->subscribe($SubscriberArray);
 
} catch (Exception $e) {
 echo $e->faultstring;
}

 

KajaKaja

Hi,

I am trying to access the apex class from jpd file using webservice.

But when i call the webservice method i am getting the Error "Invalid Session header found: Illegal Session"

My apex class
 
Code:
global class CurrencyConversion 
{
global class CurrencyInfo {
    WebService Double conversionRate;
    WebService String currencyIsoCode;
    WebService Boolean isActive;

}
    WebService static CurrencyInfo getCurrencyInfo(String curCode) {
    CurrencyInfo currInfo = new CurrencyInfo ();
    
    CurrencyType[] currencySql = [Select ConversionRate,ISOCODE,IsActive from CurrencyType where IsActive = True and ISOCODE =:curCode];
    
    currInfo.conversionRate = currencySql[0].ConversionRate;
    currInfo.currencyIsoCode = currencySql[0].ISOCODE;
    currInfo.isActive = currencySql[0].IsActive;
    return currInfo;

    }   
}

 
I've imported BOTH enterprise.wsdl and the wsdl generated from above apex class and using its method as below in JPD file
 
Code:
    /**
     * Method to set the seassion headers
     */
 private void setSessionHeaders(LoginResult lr)
    {
        SessionHeaderDocument shDoc = SessionHeaderDocument.Factory.newInstance();
        shDoc.addNewSessionHeader().setSessionId(lr.getSessionId());
        org.w3c.dom.Document domDoc = (org.w3c.dom.Document)shDoc.newDomNode();
        shElem = (org.w3c.dom.Element)domDoc.getFirstChild();
        RefreshHeaders();
        return;
    }  
 
    private void ConnectToSalesForce() throws Exception
    {
       
            try
            {
                sfdcCtrl.setEndPoint(wsdlUrl.getEndPointURL("SFDC"));
                //attempt to login using the user provided username and password
                this.parseLoginFile();
                LoginResult loginResult = sfdcCtrl.login(this.SFDCUserId, this.SFDCPwd);
           
                //set the session header with the authentication token provided by loginResult
                setSessionHeaders(loginResult);           
               
                //reset the end point to the usl specified in the loginResult
                sfdcCtrl.setEndPoint(new URL(loginResult.getServerUrl()));
            } catch (MalformedURLException e) {
                    throw new Exception("Couldnot login to SFDC.");           
            }        
    }
    public void perform() throws Exception
    {
        SvcControl.setEndPoint(wsdlUrl.getEndPointURL("Service"));
        this.ConnectToSalesForce();
    }
   
private double getExchangeRate(String currencyType)
    {

        return currencyConversionCtrl.getCurrencyInfo(currencyType).getConversionRate();      
    }

 
There is no problem while connecting to SFDC and fetch the result from jpd process but whil calling the above method it failed and server throws  "Invalid Session Id"
 
Please help me how to resolve this issue.
 
 
 
psouthcott2psouthcott2
How do we know what the right namespace is?
 
I see this page in the API docs: Namespaces in the Partner WSDL
API Calls urn:partner.soap.sforce.com 
sObjects urn:sobject.partner.soap.sforce.com 
Fields urn:sobject.partner.soap.sforce.com 
Faults urn:fault.partner.soap.sforce.com 
I've hard-coded namespace "urn:partner.soap.sforce.com" when setting the session id in SessionHeader, but no luck. The default value from the wsdl is http://soap.sforce.com/schemas/class/MyApexClass, but that doesn't work either.
 
I create the binding with a hardcoded remote url. will this effect the namespace?
 
It is kinda a pain having two sets of servicelocators and bindings, one to login and one to call the apex class.  Can the wsdls be combined and then there'd only be one wsdl?  Why can't I make my apex call to the url returned from the loginResult.getServerUrl?
 
Will the namespace be different for the production and sandbox servers?  Oddly enough, the app continues to work in production but fails against the sandbox.  I get the same error:
 
INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session. Session not found, missing session key: 123mysessionvalue123123
 
Seems crazy that it says the session id is not found and then prints the session id as part of the error string.
 
I've tried all the namespace values that I can think of.  My login connection is made to:
My next apex connection is made to:

Might the problem be related to the tapp0-api sandbox server?
 
Many thanks,
hemmhemm
I was having trouble connecting to Apex Web Services a while ago and this thread is where I found the beginnings of the answers.  After lots of trial and error, I finally got it working.

I blogged a simple example of how to setup PHP to talk to Apex Web Service that I think should answer most of the questions in this thread.  The end result is pretty simple.  Bottom line is that you will have your normal $sfdc variable to talk to the regular Salesforce API and you'll be setting up a new SoapClient variable that you will use to communicate with the web services. 

http://sfdc.arrowpointe.com/2008/12/05/calling-apex-web-services-from-php/
http://sfdc.arrowpointe.com/2008/12/05/calling-apex-web-services-from-php/
Ron WildRon Wild
Check the endpoint defined in your Apex Class WSDL file.

You may something like:

   <soap:address location="https://na5-api.salesforce.com/services/Soap/class/[namespace]/[Classname]"/>

and need:

   <soap:address location="https://cs2-api.salesforce.com/services/Soap/class/[namespace]/[Classname]"/>

instead.

You'll have to use the the correct server id for your sandbox of course (cs1, cs2, ...).



PannarPannar
Is there any way to restrict the user to entering duplicate opportunity name when he/she save the opportunity record?
 
 
Ron WildRon Wild
Please start a new thread for this new topic.
PannarPannar

Ok sure. Could you answer my query on this post regarding the same.

http://community.salesforce.com/sforce/board/message?board.id=apex&thread.id=10423

John James 67John James 67
Learn PHP online from the best PHP tutorials & courses recommended by the programming community. Follow this page to get notified about tutorials https://php.org/
simply buzzes 9simply buzzes 9
Very amazing but could you please have a look on my site (https://metrabit.com) and recommend me how can i upgrade my site according to my competitor?