承接 ahmedwaleed/soquel 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

ahmedwaleed/soquel

Composer 安装命令:

composer require ahmedwaleed/soquel

包简介

An ORM solution for Salesforce Object Query Language (SOQL)

README 文档

README

Laravel

Laravel SOQL query builder provides a convenient, fluent interface to creating, updating, SOQL queries and fetching records from salesforce.

Requirements

This Package uses omniphx/forrest package as salesforce client to fetch records from salesforce, please refer to package github page for installation and configuration guide.

Installation

You can install the package via composer:

composer require ahmedwaleed/soquel

Optionally, you can publish the config file of package.

php artisan vendor:publish --provider="Omniphx\Forrest\Providers\Laravel\ForrestServiceProvider::class"

Set following config with your salesforce credentials.

'credentials' => [
    // Required:
    'consumerKey' => env('SF_CONSUMER_KEY'),
    'consumerSecret' => env('SF_CONSUMER_SECRET'),
    'callbackURI' => env('SF_CALLBACK_URI'),
    'loginURL' => env('SF_LOGIN_URL'),

    // Only required for UserPassword authentication:
    'username' => env('SF_USERNAME'),
    // Security token might need to be ammended to password unless IP Address is whitelisted
    'password' => env('SF_PASSWORD'),
]

Update the storage type to Session or Cache, only these storage types are suppored at this time.

'storage'        => [
    'type'          => 'cache', // Options include: 'session', 'cache', 'object'
    'path'          => 'forrest_', // unique storage path to avoid collisions
    'expire_in'     => 60, // number of minutes to expire cache/session
    'store_forever' => false, // never expire cache/session
]

Basic Usage

The content of config file will be published at config/soquel.php

  • Retrieving All Rows From A Object
use AhmadWaleed\Soquel\SOQL;

echo SOQL::object('Account')->select('Id', 'Name')->toSOQL();

// Output: SELECT Id, Name FROM Account 
  • Where Clauses
SOQL::object('Account')->select('Id', 'Name')->where('Id', '=', 's3dty')->toSOQL();
SOQL::object('Account')->select('Id', 'Name')->where('Name', 'Like', '%john%')->toSOQL();
  • Additional Where Clauses
SOQL::object('Account')->select('Id', 'Name')->where('Id', '=', 's3dty')->orWhere('Id', '=', '2abc')->toSOQL();
SOQL::object('Account')->select('Id', 'Name')->whereIn('Id', ['s3dty', 'ty4ii'])->toSOQL();
SOQL::object('Account')->select('Id', 'Name')->whereNull('Name')->toSOQL();
SOQL::object('Account')->select('Id', 'Name')->whereNotNull('Name')->toSOQL();
SOQL::object('Account')->select('Id', 'Name')->whereRaw("DISTANCE(Contact__r.Geolocation__c, GEOLOCATION(15.623,35.949), 'km') < 1000")->toSOQL();
  • Select Sub Query
SOQL::object('Account')->select('Id', 'Name')->selectSub(SOQL::object('Contact')->select('Id', 'Name'))->toSOQL();
  • Subquery Where Clauses
SOQL::object('Account')->select('Id')->whereIn('Id', SOQL::object('Contact')->select('Account.Id'))->toSOQL();
  • Ordering & Limit
SOQL::object('Account')->select('Id')->orderBy('Id')->toSOQL(); // default order DESC
SOQL::object('Account')->select('Id')->orderBy('Name', 'ACS')->toSOQL();
SOQL::object('Account')->select('Id')->limit(1)->toSOQL();

ORM Usage

Query Builder is good when you want full control over query, but it becomes cumbersome with a query where you need to select all the fields of an object or want to load child pr parent object rows. This package also provide object-relational-mapper (ORM) support that makes it easy and enjoyable to interact with soql.

Generate Object Classes

To get started, lets create an Object class which by default lives in app/Objects directory and extend the AhmadWaleed\Soquel\Object\BaseObject class, but you can change the default directory in the configuration file. You may use the make:object artisan command to generate a new object class:

php artisan make:object Account

The above command will generate following class:

<?php

namespace App\Objects;

use AhmadWaleed\Soquel\Object\BaseObject;

class Account extends BaseObject
{
}

If you would like to generate a custom object class you may use the --type or -t option:

php artisan make:object Job --type=custom

The above command will generate following class:

<?php

namespace App\Objects;

use AhmadWaleed\Soquel\Object\BaseObject;

class Job extends BaseObject
{
    protected string $sobject = 'Job__c';
}

By default, the Id field of salesforce object will be retrieved, You can also define on the model what fields you want to bring back with each record.

public array $fields = [
    'Name',
    'Email',
];

By default, the Id filed is readonly, You can specify which fileds should be excluded while performing insert/update operation on model.

protected array $readOnly = ['Name'];

Retrieving Objects

Once you have created an object, you are ready to start retrieving data from salesforce, You can think of each object class as a powerful query builder allowing you to fluently query salesforce object data. The get method will retrieve all (limited to 2000 by salesforce) of the records from the associated object.

use App\Objects\Account;

foreach(Account::new()->query()->get() as $account) {
    echo $account->name;
}

Building Queries

Each Object class serves as query builder you add additional constraints to queries and invoke the get method to retrieve the results:

$accounts = Account::new()
                ->query()
                ->where('name', 'LIKE', '%john%')
                ->limit(10)
                ->get();

Collections

As we have seen, Object method like get retrieve multiple records from the salesforce. However, these methods don't return a plain PHP array. Instead, an instance of Illuminate\Database\Eloquent\Collection is returned.

The Object class extends Laravel's base Illuminate\Support\Collection class, which provides a variety of helpful methods for interacting with data collections. For example, the reject method may be used to remove objects from a collection based on the results of an invoked closure

$accounts = Account::new()->query()->whereNotNull('Email')->get();
$accounts = $accounts->reject(fn (Account $account) => $account->isActive);

Relationships

Salesforce's objects are often related to one another. For example, a Account may have many Contacts, or an Contact could be related to the Account. SOQL ORM makes managing and working with these relationships easy, and supports parent and child relationships:

Defining Relationships

Relationships are defined as methods on your Object classes. Since relationships also serve as powerful query builders, defining relationships as methods provides powerful method chaining and querying capabilities. For example, we may chain additional query constraints on this contacts relationship:

$account->contacts()->where('Name', 'LIKE', '%john%');

But, before diving too deep into using relationships, let's learn how to define each type of relationship.

Child To Parent

A child-to-parent relationship is a very basic type of salesforce relationship. For example, a Contact object might be associated with one Account object. To define this relationship, we will place a account method on the Contact object. The account method should call the parentRelation method and return its result. The parentRelation method is available to your model via the object AhmadWaleed\Soquel\Object\BaseObject base class:

<?php

namespace AhmadWaleed\Soquel\Tests\Objects;

use AhmadWaleed\Soquel\Object\BaseObject;
use AhmadWaleed\Soquel\Object\ParentRelation;

class Contact extends BaseObject
{
    public Account $account;
    
    public function account(): ParentRelation
    {
        return $this->parentRelation(Account::class);
    }
}

The first argument passed to the parentRelation method is the name of the related object class. Once the relationship is defined, we may retrieve the related record with following query:

$account = Contact::new()->query()->with('account')->find('id')->account;

Additionally, you can pass object type and relationship name in second and third argument to parentRelation method;

return $this->parentRelation(Job::class, 'Job__c');

For custom objects orm assumes relationship name, For example for custom object Job__c the relationship name will be Job__r, But if you want to override the default convention you can pass relationship name as third argument.

return $this->parentRelation(Job::class, 'Job__c', 'jobs');

Parent To Child

A parent-to-child relationship is used to define relationships where a single object is the parent to one or more child objects. For example, a account may have an infinite number of contacts. Like all other Salesforce relationships, parent-to-child relationships are defined by defining a method on your Object class:

<?php

namespace AhmadWaleed\Soquel\Tests\Objects;

use AhmadWaleed\Soquel\Object\BaseObject;
use AhmadWaleed\Soquel\Object\ChildRelation;
use Illuminate\Support\Collection;

class Account extends BaseObject
{
    public Collection $contacts;
    
    public function contacts(): ChildRelation
    {
        return $this->childRelation(Contact::class);
    }
}

The first argument passed to the childRelation method is the name of the related object class. Once the relationship is defined, we may retrieve the related records with following query:

$contacts = Account::new()->query()->with('contacts')->find('id')->contacts;

Additionally, you can pass object type and relationship name in second and third argument to childRelation method;

return $this->childRelation(Attachment::class, 'Attachment__c');

For custom objects orm assumes relationship name, For example for custom object Attachment__c the relationship name will be Attachment__r, But if you want to override the default convention you can pass relationship name as third argument.

return $this->childRelation(Attachment::class, 'Attachment__c', 'attachments');

Inserting and Updating

  • Insert
$contact = new Contact();
$contact->LastName = 'doe';
$contact->Email = 'john@example.com';
$contact->save();

// OR 

$contact = Contact::create(['LastName' => 'doe', 'Email', 'john@example.com']);
  • Insert Collection
$contacts = collect([
	new Contact(['Email' => 'email1@test.com']),
	new Contact(['Email' => 'email2@test.com'])
]);

Contact::saveMany($contacts);

// OR

$contacts = collect([
	['Email' => 'email1@test.com'],
	['Email' => 'email2@test.com']
]);

Contact::saveMany($contacts);
  • Update
$contact = new Contact();
$contact->LastName = 'michael';
$contact->save();

// OR 

$contact = $contact->update(['LastName' => 'michael', 'Email', 'michael@example.com']);

License

The MIT License (MIT). Please see License File for more information.

ahmedwaleed/soquel 适用场景与选型建议

ahmedwaleed/soquel 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 252 次下载、GitHub Stars 达 4, 最近一次更新时间为 2021 年 01 月 09 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「orm」 「salesforce」 「laravel」 「soql」 「AhmadWaleed」 「salesforce object query language」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 ahmedwaleed/soquel 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 ahmedwaleed/soquel 我们能提供哪些服务?
定制开发 / 二次开发

基于 ahmedwaleed/soquel 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 252
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 4
  • 点击次数: 8
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 4
  • Watchers: 1
  • Forks: 3
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2021-01-09