panobit/connectwise-php-client

ConnectWise 管理的集成。


README

Latest Stable Version Total Downloads Latest Unstable Version License

ConnectWise RESTful API 的 PHP 客户端。

我们仅使用 Laravel 进行我们的应用程序开发,因此,如果您在 Laravel 应用程序中使用此客户端,可以使用一些 Laravel 特定的文件。我们已经尽力确保您可以在 Laravel 之外使用客户端,并在以下文档中提供了一些相关信息。

构建状态

分支状态覆盖率代码质量
开发Build StatusCode CoverageScrutinizer Code Quality
主分支Build StatusCode CoverageScrutinizer Code Quality

关于集成的说明

我们使用“成员伪装”模型,您需要设置一个具有“成员 API”访问权限的集成器用户名和密码,这样所有对 ConnectWise 的调用都将在应用程序(成员 ID)用户的权限下执行。

我们将所有 ConnectWise 用户的成员 ID 设置为他们自己的电子邮件(例如,joe.doe@spinen.com 的成员 ID 为 joedoe 在 connectwise),[注意:从 joe.doe 中删除了点,因为 ConnectWise 不允许在成员 ID 中使用点]。通过遵循此约定,我们可以从我们的应用程序中登录用户的电子邮件地址中推断出成员 ID。我们包含了一个可以用于 User 模型的特质,该特质将执行上述逻辑。

截至 2019.3,他们需要连接到 API 时的 clientId,因此您需要在此处注册...

https://developer.connectwise.com/ClientID

支持的操作

客户端支持标准的 http verbs 加一个额外的...

  • delete
  • get(ConnectWise 默认分页为 25 条记录,除非您指定不同的 pageSize,否则您将获得 25 条记录)
  • getAll(进行尽可能多的 API 调用来获取集合中的所有记录。当使用此方法时,请务必小心,因为您的系统可能会耗尽内存。)
  • head
  • put
  • post
  • patch

模型

响应被转换为具有属性转换为 Swagger 文档中定义的类型。您可以在 src/Models 文件夹中查看模型。每个模型上都有一个名为 casts 的属性,它指导工厂如何将响应中的属性转换为类型。如果 casts 属性为空,则属性未定义在 Swagger 中,因此返回一个数组。

关系

一些响应包含到相关资源的链接。如果属性有关系,您可以将其作为方法调用,额外的调用将自动进行并返回。值将存储在原始数据的位置,因此一旦加载,它将被缓存。

$ psysh
Psy Shell v0.8.18 (PHP 7.2.17 — cli) by Justin Hileman

>>> // Using "$member" object for this example
>>> get_class($member) // Verify that it is a "Member"
=> "Spinen\ConnectWise\Models\v2019_3\System\Member"
>>> get_class($member->defaultLocation) // On load, the "defaultLocation" is a "SystemLocationReference" object
=> "Spinen\ConnectWise\Models\v2019_3\System\SystemLocationReference"
>>> get_class($member->defaultLocation()) // Call it as a method to load the relationship
=> "Spinen\ConnectWise\Models\v2019_3\System\Location"
>>> get_class($member->defaultLocation) // Now it is cached as a "Location" object
=> "Spinen\ConnectWise\Models\v2019_3\System\Location"

在 "_info" 属性中也可能有“相关”属性,您可以让系统为您加载。 [注意:这将为相关属性执行 getAll,因此将根据需要执行尽可能多的 API 调用来获取所有相关项]

$ psysh
Psy Shell v0.8.18 (PHP 7.2.17 — cli) by Justin Hileman

>>> // Using "$company" object for this example
>>> get_class($company) // Verify that it is a "Company"
=> "Spinen\ConnectWise\Models\v2018_6\Company\Company"
>>> $company->_info // Look for potential relations
=> Spinen\ConnectWise\Models\v2018_6\Company\Metadata {#5678
     +"lastUpdated": "2019-05-20T18:12:38Z",
     +"updatedBy": "someone",
     +"dateEntered": "2006-06-21T16:04:59Z",
     +"enteredBy": "someone",
     +"contacts_href": "https://some.host/v4_6_release/apis/3.0/company/contacts?conditions=company/id=250",
     +"agreements_href": "https://some.host/v4_6_release/apis/3.0/finance/agreements?conditions=company/id=250",
     +"tickets_href": "https://some.host/v4_6_release/apis/3.0/service/tickets?conditions=company/id=250",
     +"opportunities_href": "https://some.host/v4_6_release/apis/3.0/sales/opportunities?conditions=company/id=250",
     +"activities_href": "https://some.host/v4_6_release/apis/3.0/sales/activities?conditions=company/id=250",
     +"projects_href": "https://some.host/v4_6_release/apis/3.0/project/projects?conditions=company/id=250",
     +"configurations_href": "https://some.host/v4_6_release/apis/3.0/company/configurations?conditions=company/id=250",
     +"orders_href": "https://some.host/v4_6_release/apis/3.0/sales/orders?conditions=company/id=250",
     +"documents_href": "https://some.host/v4_6_release/apis/3.0/system/documents?recordType=Company&recordId=250",
     +"sites_href": "https://some.host/v4_6_release/apis/3.0/company/companies/250/sites",
     +"teams_href": "https://some.host/v4_6_release/apis/3.0/company/companies/250/teams",
     +"reports_href": "https://some.host/v4_6_release/apis/3.0/company/companies/250/managementSummaryReports",
     +"notes_href": "https://some.host/v4_6_release/apis/3.0/company/companies/250/notes",
   }
>>> isset($company->agreements) // Not loaded before the call
=> false
>>> $company->agreements // Client goes to get "agreements" from the $company->_info->agreements_fref URI
=> Spinen\ConnectWise\Support\Collection {#6123
     // Removed to make example shorter
   }
>>> isset($company->agreements) // Cached & loaded for next call
=> true

安装

安装 ConnectWise PHP 客户端

$ composer require spinen/connectwise-php-client

Laravel 配置和使用

对于 >= Laravel 5.5,安装完成

该包使用 Laravel 5 的 自动注册功能

对于 < Laravel 5.5,您必须注册 Service Provider

  1. 将提供程序添加到 `config/app.php`
    'providers' => [
        # other providers omitted
        Spinen\ConnectWise\Laravel\ServiceProvider::class,
    ],
  1. [可选] 将别名添加到 `config/app.php`
    'aliases' => [
        # other aliases omitted
        'ConnectWise' => Spinen\ConnectWise\Laravel\Facades\ConnectWise::class,
    ],

配置

  1. 将以下内容添加到 `config/services.php`...
    'connectwise' =>  [
        'client_id' => env('CW_CLIENT_ID'),
        'company_id' => env('CW_COMPANY_ID'),
        // Optional member id to use if there is not a logged in user
        'default_member_id' => env('CW_DEFAULT_MEMBER_ID'),
        'integrator' => env('CW_INTEGRATOR'),
        'password' => env('CW_PASSWORD'),
        'url' => env('CW_URL'),
        // Optional version of the API models to use
        //'version' => '' // default is the latest supported
    ],
  1. 将适当的值添加到您的 `.env`...
CW_CLIENT_ID=<the-client-id>
CW_COMPANY_ID=<company_id>
CW_DEFAULT_MEMBER_ID=<default_member_id>
CW_INTEGRATOR=<integrator username>
CW_PASSWORD=<integrator password>
CW_URL=https://<FQDN to ConnectWise server>
  1. 在用户模型上使用`ConnectWiseMemberIdFromEmail特性,该特性位于Spinen\ConnectWise\Laravel\ConnectWiseMemberIdFromEmail`,如果你的ConnectWise成员ID与上述描述的电子邮件相匹配。如果不遵循该约定,则可以在用户模型上定义自己的`getConnectWiseMemberIdAttribute访问器,或者在用户表中添加一个connect_wise_member_id`列,并用适当的值填充。

用法

以下是一个获取系统信息的示例...

从版本3.1.0开始,响应可以是Laravel模型集合或单个模型。您可以在`src/Models`中看到这些模型。它们都扩展了`Spinen\ConnectWise\Support`,因此您可以查看它们提供的方法。

$ php artisan tinker
Psy Shell v0.8.0 (PHP 7.0.14 — cli) by Justin Hileman
>>> Auth::loginUsingId(1); // If not useing the default member id
=> App\User {#983
     id: "1",
     first_name: "Joe",
     last_name: "Doe",
     email: "joe.doe@domain.tld",
     admin: "0",
     created_at: "2017-01-02 18:30:47",
     updated_at: "2017-01-12 22:22:39",
     logged_in_at: "2017-01-12 22:22:39",
     deleted_at: null,
   }
>>> $cw = app('Spinen\ConnectWise\Api\Client');
=> Spinen\ConnectWise\Api\Client {#934}
>>> $info = $cw->get('system/info');
=> Spinen\ConnectWise\Models\v2019_3\System\Info {#1008}
>>> $info->toArray();
=> [
     "version" => "v2016.6.43325",
     "isCloud" => false,
     "serverTimeZone" => "Eastern Standard Time",
   ]
>>> $info->toJson()
=> "{"version":"v2016.6.43325","isCloud":false,"serverTimeZone":"Eastern Standard Time"}"
>>> $info->isCloud
=> false
>>> $info['isCloud'];
=> false

使用外观进行相同的调用...

$ php artisan tinker
Psy Shell v0.8.0 (PHP 7.0.14 — cli) by Justin Hileman
>>> Auth::loginUsingId(1);  // If not useing the default member id
=> App\User {#983
     id: "1",
     first_name: "Joe",
     last_name: "Doe",
     email: "joe.doe@domain.tld",
     admin: "0",
     created_at: "2017-01-02 18:30:47",
     updated_at: "2017-01-12 22:22:39",
     logged_in_at: "2017-01-12 22:22:39",
     deleted_at: null,
   }
>>> ConnectWise::get('system/info');
=> Spinen\ConnectWise\Models\v2019_3\System\Info {#1005}
>>> ConnectWise::get('system/info')->toArray();
=> [
        "version" => "v2018.6.59996",
        "isCloud" => false,
        "serverTimeZone" => "Eastern Standard Time",
        "licenseBits" => [
          // ... All of the properties
        ],
        "cloudRegion" => "NA",
      ]
>>> ConnectWise::get('system/info')->toJson();
=> "{"version":"v2018.6.59996",...}"
>>> ConnectWise::get('system/info')->isCloud;
=> false
>>> ConnectWise::get('system/info')['isCloud'];
=> false
>>>

非Laravel用法

要在Laravel之外使用客户端,只需创建对象...

$ psysh
Psy Shell v0.8.18 (PHP 7.2.17 — cli) by Justin Hileman

>>> // New-up objects
>>> $token = (new Spinen\ConnectWise\Api\Token())->setCompanyId('<company_id>')->setMemberId('<member_id>');
=> Spinen\ConnectWise\Api\Token {#208}
>>> $guzzle = new GuzzleHttp\Client();
=> GuzzleHttp\Client {#196}
>>> $resolver = new Spinen\ConnectWise\Support\ModelResolver();
=> Spinen\ConnectWise\Support\ModelResolver {#201}
>>> $client = (new Spinen\ConnectWise\Api\Client($token, $guzzle, $resolver))->setClientId('<the-client-id>')->setIntegrator('<integrator>')->setPassword('<password>')->setUrl('https://<domain.tld>');
=> Spinen\ConnectWise\Api\Client {#231}
>>> $info = $client->get('system/info');                                                                                                                     => Spinen\ConnectWise\Models\v2019_3\System\Info {#237}
>>> $info->toArray();
=> [
     "version" => "v2018.6.59996",
     "isCloud" => false,
     "serverTimeZone" => "Eastern Standard Time",
     "licenseBits" => [
       // ... All of the properties
     ],
     "cloudRegion" => "NA",
   ]
>>> // Set client to use different version
>>> $client->setVersion('2019.1')
=> Spinen\ConnectWise\Api\Client {#231}
>>> $info = $client->get('system/info');
>>> /// NOTE: the version in the namespace
=> Spinen\ConnectWise\Models\v2019_1\System\Info {#235}

支持的API模型版本

您可以通过以下3种方式之一指定所需的模型版本...

  1. Client构造函数中的第4个参数
  2. client对象上调用setVersion方法
  3. [仅Laravel] 在配置中设置version属性

支持的版本有

  • 2018.4
  • 2018.5
  • 2018.6
  • 2019.1
  • 2019.2
  • 2019.3
  • 2019.4
  • 2019.5 (默认)

您可以通过查看src/Models/<version>目录中各个modelscasts属性来查看模型之间的差异。