fromholdio / salesforce-rest-sdk
用于 Salesforce Rest API 的 SDK
Requires
- php: ^7.2|^8.0
- doctrine/collections: ^1.6
- guzzlehttp/guzzle: ^7.3
- jms/metadata: ^1.0|^2.0
- jms/serializer: ^3.12
- psr/log: ^1.1
- ramsey/uuid: ^4.1
- symfony/cache: ^4.0|^5.0|^6.0
- symfony/expression-language: ^4.2|^5.0|^6.0
Requires (Dev)
- phpunit/phpunit: ^7.3
- dev-master
- 3.0.0
- v2.0.3
- v2.0.2
- v2.0.1
- 2.0.0
- v1.4.0
- v1.3.8
- v1.3.7
- v1.3.6
- v1.3.5
- v1.3.4
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.5
- v1.2.4
- v1.2.3
- v1.2.2
- v1.2.1
- v1.2
- v1.1.17
- v1.1.16
- v1.1.15
- v1.1.14
- v1.1.13
- v1.1.12
- v1.1.11
- v1.1.10
- v1.1.9
- v1.1.8
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.0
- dev-feature/playable
- dev-feature/ExtensionOnChannelsFireOnConnect
- dev-develop
- dev-curiosity26/csv-fixes
This package is auto-updated.
Last update: 2024-09-04 11:02:07 UTC
README
此 API 支持以下 Salesforce API 区域
- 限制
- 全局描述
- SObject 描述
- SObject CRUD
- SObject 获取更新/删除
- 复合 API
- 批量处理
- 树形结构
- SObject 集合
- 批量 API
- 流式 API
安装
composer require ae/salesforce-rest-sdk
实例化 Rest 客户端
<?php use AE\SalesforceRestSdk\Rest\Client; use AE\SalesforceRestSdk\AuthProvider\OAuthProvider; $client = new Client( new OAuthProvider( "SF_CLIENT_ID", "SF_CLIENT_SECRET", "https://login.salesforce.com", "SF_USER", "SF_PASS" ), "46.0", // optional version number, defaults to 44.0 "MyAppName" // optional client app name, used when filtering out Change Data Events in the Streaming API );
有关使用客户端应用名称与更改数据捕获的信息,请参阅 https://developer.salesforce.com/docs/atlas.en-us.change_data_capture.meta/change_data_capture/cdc_event_fields_header.htm
如果您返回到 redirectUrl 的授权代码并希望使用它,可以像这样操作
<?php use AE\SalesforceRestSdk\Rest\Client; use AE\SalesforceRestSdk\AuthProvider\OAuthProvider; $client = new Client( new OAuthProvider( "SF_CLIENT_ID", "SF_CLIENT_SECRET", "https://login.salesforce.com", null, null, OAuthProvider::GRANT_CODE, "https://your.redirect.uri", "THE_CODE_FROM_SALESFORCE" ) );
缓存的身份验证提供者
缓存的身份验证提供者提供了一种在请求之间保留有效凭据的方法,否则客户端将在每次实例化时都使用 Salesforce 进行身份验证。
<?php use AE\SalesforceRestSdk\Rest\Client; use AE\SalesforceRestSdk\AuthProvider\CachedOAuthProvider; use Symfony\Component\Cache\Adapter\FilesystemAdapter; // Any adapter that uses Psr\Cache\CacheItemPoolInterface will work with the Cached Providers $adapter = new FilesystemAdapter(); $client = new Client( new CachedOAuthProvider( $adapter, "SF_CLIENT_ID", "SF_CLIENT_SECRET", "https://login.salesforce.com", null, null, CachedOAuthProvider::GRANT_CODE, "https://your.redirect.uri", "THE_CODE_FROM_SALESFORCE" ) );
在没有框架的情况下使用 Composer 自动加载
如果您没有使用像 Symfony 这样为您处理注解注册的 PHP 框架,则必须自行完成此操作
<?php use AE\SalesforceRestSdk\Rest\Client; use AE\SalesforceRestSdk\AuthProvider\OAuthProvider; use Doctrine\Common\Annotations\AnnotationRegistry; $loader = require_once 'vendor/autoload.php'; AnnotationRegistry::registerLoader(array($loader, "loadClass")); $client = new Client( // ...
使用 SObject 客户端处理 SObjects
<?php //... /** @var \AE\SalesforceRestSdk\Rest\SObject\Client $sObjectClient */ $sObjectClient = $client->getSObjectClient(); // Get basic metadata and recently used records for an object $info = $sObjectClient->info("Account"); // Get very detailed metadata about an object $describe = $sObjectClient->describe("Account"); // Get basic metadata info about all objects in SF $globalDescribe = $sObjectClient->describeGlobal(); // Let's CRUD it up $account = new \AE\SalesforceRestSdk\Model\SObject(); $sObjectClient->persist("Account", $account); // returns true if success echo $account->Id; // outputs the SFID of the account $account->MyCustomField__c = "Some Value I want to Save"; $sObjectClient->persist("Account", $account); // returns true on success // Let's get new info from out account, pretend it was updated in SF $account = $sObjectClient->get("Account", $account->Id, ["Name", "AnotherCoolField__c"]); // Kill the account $sObjectClient->remove("Account", $account); // Query for more stuff $result = $sObjectClient->query("SELECT Id, Name FROM Account"); echo $result->getTotalSize(); // OUtputs the total number of records for the query var_dump($result->getRecords()); // SObject[] while (!$result->isDone()) { // There are more records to be returned! // Just pass in the last result set and get the next batch // Lather, rinse, repeat until $result->isDone() === true; $result = $sObjectClient->query($result); var_dump($result->getRecords()); // CompositeSObject[] } // Query deleted and merged records, too $result = $sObjectClient->queryAll( "SELECT Id, Name FROM Account", 1000 // optional batch size, defaults to 2000, which is the max, min is 200 ); // Search for something $result = $sObjectClient->search("FIND {Some Query} IN ALL FIELDS"); var_dump($result->getSearchRecords()); // CompositeSObject[]
有关批量大小和 Sforce-Query-Options 标头的更多信息,请参阅 https://developer.salesforce.com/docs/atlas.en-us.220.0.api_rest.meta/api_rest/headers_queryoptions.htm。
需要注意的是,如果批量大小不是最优性能,Salesforce 可能不会遵守批量大小。
实例化流式客户端
<?php use AE\SalesforceRestSdk\Bayeux\BayeuxClient; use AE\SalesforceRestSdk\AuthProvider\OAuthProvider; use AE\SalesforceRestSdk\Bayeux\Transport\LongPollingTransport; $client = new BayeuxClient( new LongPollingTransport(), new OAuthProvider( "SF_CLIENT_ID", "SF_CLIENT_SECRET", "https://login.salesforce.com", "SF_USER", "SF_PASS" ), "46.0" // optional version number, defaults to 44.0 );
订阅 PushTopic
您可以使用上面的 Rest 客户端创建新的 PushTopic。在 Salesforce Org 中只需创建一次即可。所有自定义对象都由 Streaming API 支持,但是并非所有标准对象都支持。
支持的标准对象
- 账户
- 活动
- 案例
- 联系人
- 合同行项目
- 权益
- 潜在客户
- 实时聊天记录
- 机会
- 报价
- 报价行项目
- 服务合同
- 任务
以下方法创建或更新创建的任务不会在流式 API 中的任务对象主题中出现。
- 潜在客户转换
- 实体合并
- 批量电子邮件联系人/潜在客户
<?php use AE\SalesforceRestSdk\Bayeux\BayeuxClient; use AE\SalesforceRestSdk\Bayeux\Consumer; use AE\SalesforceRestSdk\Bayeux\ChannelInterface; use AE\SalesforceRestSdk\Bayeux\Message; use AE\SalesforceRestSdk\Bayeux\Extension\ReplayExtension; use AE\SalesforceRestSdk\Bayeux\Extension\CachedReplayExtension; use Symfony\Component\Cache\Adapter\FilesystemAdapter; /** @var BayeuxClient $client */ // Getting a channel tells the client you want to subscribe to a topic $channel = $client->getChannel('/topic/[YOUR_PUSH_TOPIC_NAME]'); // Give some durability to the messages on this channel by adding the ReplayExtension $channel->addExtension(new ReplayExtension(ReplayExtension::REPLAY_SAVED)); // Using the CachedReplayExtension give greater durability in that it will remember the replay Id of the last // message received and pick up where it left off, even if the process stops and restarts. If no messages for the // channel topic have been received, it will use the value provided in the constructor. // Again, Any Psr\Cache\CacheItemPoolInterface will do for the adapter parameter $channel->addExtension(new CachedReplayExtension(new FilesystemAdapter(), CachedReplayExtension::REPLAY_SAVED)); // You can also apply extensions at the Client level, rather than the channel. // In the case of the ReplayExtension, the last replayId will be remembered for each channel, // however, if no messages have been received on the channel, the constructor argument is used $client->addExtension(new CachedReplayExtension(new FilesystemAdapter(), CachedReplayExtension::REPLAY_SAVED)); // Register topic consumers prior to starting the client $channel->subscribe( Consumer::create(function (ChannelInterface $channel, Message $message) { // This will be fired when the client receives a topic notification $payload = $message->getData(); // The payload has information about the event that occurred $event = $payload->getEvent(); echo $event->getType(); // "created", "updated", "undeleted", "deleted" echo $event->getCreatedDate()->format(\DATE_ISO8601); // outputs the datetime the event was created echo $event->getReplayId(); // This ia n ID used by the replay extension so it can pick up the feed where it left off $sobject = $payload->getSobject(); echo $sobject->Id; // Get the Id echo $sobject->getFields(); // this outputs all the fields and their values that were in the create or update request }) ); // Start the client to begin receiving notifications; $client->start();
$client->start();
是一个阻塞调用,在客户端发生错误并断开连接之前,它之后的代码将不会执行。例如,客户端必须在接收到每次通知后 40 秒内重新连接到流式服务器。如果它未能这样做,它将尝试重新握手以创建新的连接。如果这失败,客户端将断开连接,这将允许脚本的其他部分执行。
建议在单独的线程中运行流式客户端
分发通用事件
创建流式通道
在您可以分发通用事件之前,您必须创建流式通道。这可以通过多种方式完成
- 通过 Salesforce Classic UI,如以下文档所述
- 在设置 > 用户界面下启用启用动态流媒体频道创建,然后使用流媒体客户端按上述文档订阅流媒体频道
- 流媒体频道是一个普通的SObject,可以像创建SObject一样创建
<?php use Symfony\Component\Cache\Adapter\FilesystemAdapter; use AE\SalesforceRestSdk\Rest\Client; use AE\SalesforceRestSdk\AuthProvider\CachedOAuthProvider; use AE\SalesforceRestSdk\Model\SObject; // Use the SObject Client to create a Streaming Channel // Any adapter that uses Psr\Cache\CacheItemPoolInterface will work with the Cached Providers $adapter = new FilesystemAdapter(); $client = new Client( new CachedOAuthProvider( $adapter, "SF_CLIENT_ID", "SF_CLIENT_SECRET", "https://login.salesforce.com", "SF_USERNAME", "SF_PASSWORD" ) ); $streamingChannel = new SObject([ 'name' => '/u/MY_AWESOME_TOPIC' ]); $client->getSObjectClient()->persist('StreamingChannel', $streamingChannel);
向流媒体频道发送通用事件
一旦创建了StreamingChannel,现在可以使用GenericEventClient
将事件发送到它,它依赖于SObject客户端。让我们假设我们正在继续上面的代码,以下是一个例子
<?php use Symfony\Component\Cache\Adapter\FilesystemAdapter; use AE\SalesforceRestSdk\Rest\Client; use AE\SalesforceRestSdk\AuthProvider\CachedOAuthProvider; use AE\SalesforceRestSdk\Model\SObject; use AE\SalesforceRestSdk\Rest\GenericEventClient; use AE\SalesforceRestSdk\Model\Rest\GenericEvent; use AE\SalesforceRestSdk\Model\Rest\GenericEvents; // ... Client and everything is defined as above // Generic Event Client also takes a cache adapter which it uses to keep track of Ids for StreamingChannels. You can // resuse the adapter given to the client if you wish. The keys won't conflict. $geClient = new GenericEventClient($adapter, $client->getSObjectClient()); // Next we'll create a Generic Event to dispatch $event = new GenericEvent(); $event->setPayload("This is the payload of the event. It has to be a string. But it could be XML or JSON data"); // You can also set which clients subscribing to the channel you want to receive your message, // if you didn't want all of them getting it. Use the GenericEventClient to see which users are subscribed to the channel $users = $geClient->getChannelSubscribers('/u/MY_AWESOME_TOPIC'); $event->setUserIds($users); // Send the event to the Streaming Channel $geClient->sendEvent('/u/MY_AWESOME_TOPIC', $event); // Multiple events can also be sent at once $events = GenericEvents::create([ GenericEvent::create("Event payload magic here"), GenericEvent::create("More event payload magic here"), ]); // Send the events to the Streaming Channel $geClient->sendEvents('/u/MY_AWESOME_TOPIC', $events);
未来新增功能
- 工具API
- 元数据API