justbetter / laravel-dynamics-client
用于连接 Microsoft Dynamics 的客户端
Requires
- php: ^8.1
- justbetter/odata-client: ^1.3
- laravel/framework: ^10.0|^11.0
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.15
- orchestra/testbench: ^8.0|^9.0
- phpstan/phpstan-mockery: ^1.1
- phpunit/phpunit: ^10.0
README
Laravel Dynamics Client
此包将通过 OData 将您连接到 Microsoft Dynamics 网络服务。可以轻松实现自定义网络服务并将其映射到您的喜好。它使用 Laravel 的 HTTP 客户端,这意味着您可以在编写测试时轻松模拟请求。
我们与 OData 交互的方式受到了 Laravel 查询构建器(QueryBuilder)的启发。
$customer = Customer::query()->findOrFail('1000'); $customer->update([ 'Name' => 'John Doe', ]); $customers = Customer::query() ->where('City', '=', 'Alkmaar') ->lazy(); $items = Item::query() ->whereIn('No', ['1000', '2000']) ->get(); $customer = Customer::new()->create([ 'Name' => 'Jane Doe', ]);
安装
安装 composer 包。
composer require justbetter/laravel-dynamics-client
设置
发布包的配置。
php artisan vendor:publish --provider="JustBetter\DynamicsClient\ServiceProvider" --tag=config
配置
在 .env
中添加您的 Dynamics 凭据。
DYNAMICS_BASE_URL=https://127.0.0.1:7048/DYNAMICS
DYNAMICS_VERSION=ODataV4
DYNAMICS_COMPANY=
DYNAMICS_USERNAME=
DYNAMICS_PASSWORD=
DYNAMICS_PAGE_SIZE=1000
确保 DYNAMICS_PAGE_SIZE
设置与 Dynamics 配置中的 OData Services
下的 Max Page Size
相同。这对于 QueryBuilder
的 lazy
方法的功能至关重要。
身份验证
注意:请确保 Dynamics 已正确配置 OData。
默认情况下,此包使用 NTLM 身份验证。如果您需要使用基本身份验证或 OAuth,您可以在 .env
中更改此设置。
DYNAMICS_AUTH=basic
OAuth
要设置 OAuth,请将以下内容添加到您的 .env
文件中
DYNAMICS_AUTH=oauth DYNAMICS_OAUTH_CLIENT_ID= DYNAMICS_OAUTH_CLIENT_SECRET= DYNAMICS_OAUTH_REDIRECT_URI= DYNAMICS_OAUTH_SCOPE=
当使用 D365 云与 Microsoft identity platform 时,您的重定向 URI 将是: https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token
,并且您的基本 URL 应该是 https://api.businesscentral.dynamics.com/v2.0/<tenant>/<environment>
。
连接
支持多个连接。您可以轻松更新 dynamics
配置以添加任意数量的连接。
// Will use the default connection. Customer::query()->first(); // Uses the supplied connection. Customer::query('other_connection')->first();
默认情况下,客户端将使用 company
字段来选择 Dynamics 公司。如果您希望使用公司的 UUID,可以简单地添加一个 uuid
字段
'Company' => [ 'base_url' => env('DYNAMICS_BASE_URL'), 'version' => env('DYNAMICS_VERSION', 'ODataV4'), 'company' => 'Company Name', 'uuid' => 'Company UUID', // The UUID will be prioritized over the company name
添加网络服务
将网络服务添加到您的配置中很简单。首先创建自己的资源类以映射数据。
use JustBetter\DynamicsClient\OData\BaseResource; class Customer extends BaseResource { // }
主键
默认情况下,资源的默认主键为字符串 No
。您可以通过提供变量 $primaryKey
来覆盖此设置。
public array $primaryKey = [ 'Code', ];
数据类型转换
默认情况下,资源中的字段将被视为字符串。对于某些字段,如行号,应将其转换为整数。
public array $casts = [ 'Line_No' => 'int', ];
注册资源
最后,您应在配置文件中注册您的资源,以便包知道网络服务所在位置。这应与 Dynamics 中配置的服务名称相对应。
如果您的资源类名称与服务名称相同,则不需要手动配置。
注意:确保您的网络服务已发布。
return [ /* Resource Configuration */ 'resources' => [ Customer::class => 'CustomerCard', ], ];
查询构建器
使用 QueryBuilder 可以轻松地进行数据查询。
使用 get
方法只会返回第一页的结果。如果您希望有效地遍历所有记录,请使用 lazy
。
$customers = Customer::query() ->where('City', '=', 'Alkmaar') ->lazy() ->each(function(Customer $customer): void { // });
请参阅 QueryBuilder
类以了解所有可用方法。
关系
可以通过资源访问页面上发布的任何关系。
$salesOrder = SalesOrder::query()->first(); // Get the lines via the "relation" method. $salesLines = $salesOrder->relation('Relation_Name', SalesLine::class)->get(); // Or use the "lines" helper on the SalesOrder. $salesLines = $salesOrder->lines('Relation_Name')->get();
请注意,relation
方法本身返回一个查询构建器(QueryBuilder)的实例。这意味着您可以为常规资源添加额外的 where 子句。
创建记录
创建新记录。
Customer::new()->create([ 'Name' => 'John Doe' ])
更新记录
更新现有记录。
$customer = Customer::query()->find('1000'); $customer->update([ 'Name' => 'John Doe', ]);
删除记录
删除记录。
$customer = Customer::query()->find('1000'); $customer->delete();
调试
如果您想在发送查询之前进行审查,您可能希望使用构建器上的 dd
函数。
Customer::query() ->where('City', '=', 'Alkmaar') ->whereIn('No', ['1000', '2000']) ->dd(); // Customer?$filter=City eq 'Alkmaar' and (No eq '1000' or No eq '2000')
命令
您可以使用以下命令来检查您是否可以成功连接到 Dynamics。
php artisan dynamics:connect {connection?}
扩展
如果需要,可以通过创建自己的来扩展提供的 ClientFactory
类。您 必须 实现 ClientFactoryContract
接口及其方法。
use JustBetter\DynamicsClient\Exceptions\DynamicsException; use JustBetter\DynamicsClient\Contracts\ClientFactoryContract; class MyCustomClientFactory implements ClientFactoryContract { public function __construct(public string $connection) { $config = config('dynamics.connections.'.$connection); if (! $config) { throw new DynamicsException( __('Connection ":connection" does not exist', ['connection' => $connection]) ); } $this ->header('Authorization', 'Bearer ' . $config['access_token']) ->header('Accept', 'application/json') ->header('Content-Type', 'application/json'); } ... }
然后您需要将自定义工厂绑定为合同实现,在任何您的 ServiceProvider
注册方法中。
<?php use JustBetter\DynamicsClient\Contracts\ClientFactoryContract; class AppServiceProvider extends ServiceProvider { /** * Register the service provider. * * @return void */ public function register() { $this->app->bind(ClientFactoryContract::class, MyCustomClientFactory::class); } }
模拟 Dynamics 请求
在编写测试时,您可能需要模拟 Dynamics 的请求。幸运的是,这个包使用了 Laravel 的 HTTP 客户端,这使得模拟变得非常简单。
为了模拟所有对 Dynamics 的请求,您可以在任何资源上调用 fake
方法。
fake
方法将模拟 所有 对 Dynamics 的请求,而不仅仅是使用资源的端点。
<?php use JustBetter\DynamicsClient\OData\BaseResource; BaseResource::fake();
此方法将模拟 Dynamics 配置并移除敏感信息,如用户名和密码。仅保留公司名称,以便于测试多个连接。
<?php use Illuminate\Support\Facades\Http; use JustBetter\DynamicsClient\OData\Pages\Item; Item::fake(); Http::fake([ 'dynamics/ODataV4/Company(\'default\')/Item?$top=1' => Http::response([ 'value' => [ [ '@odata.etag' => '::etag::', 'No' => '::no::', 'Description' => '::description::', ], ], ]), ]); $item = Item::query()->first();
贡献
有关详细信息,请参阅 CONTRIBUTING。
安全漏洞
有关如何报告安全漏洞,请参阅我们的安全策略 our security policy。
鸣谢
许可证
MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件。