grantholle/powerschool-api

一个Laravel包,使与PowerSchool交互更加便捷。

4.4.2 2024-04-17 13:14 UTC

README

从Laravel的数据库和Eloquent Builder 类中汲取灵感,这使得您可以对PowerSchool进行非常流畅和自然的API请求。它自动处理令牌认证,因此您只需关注编写请求,无需编写样板代码。

此包应与已启用<oauth/>的PowerSchool插件一起使用。本指南假定您已了解PowerSchool API和插件,不涵盖插件或其API的详细信息。

版本v4的重大更改

  • 需要PHP ^8.1
  • 需要Laravel ^10.0

版本v3的重大更改

  • 需要PHP ^8.0
  • 请求现在返回一个新的Response对象,而不是stdClass,详细信息请见下文

版本v2的重大更改

版本v2添加了更多功能,并附带了测试以确保安心。

安装

composer require grantholle/powerschool-api

该包将被Laravel自动发现,因此除非您想这样做,否则无需将其添加到config/app.php中。

配置

您需要在.env中设置一些变量。

POWERSCHOOL_ADDRESS=
POWERSCHOOL_CLIENT_ID=
POWERSCHOOL_CLIENT_SECRET=

可选地,您可以发布配置文件以存储与PowerSchool交互的服务器地址、客户端ID和密钥。这将生成config/powerschool.php,但这不是必需的。

php artisan vendor:publish --provider="GrantHolle\PowerSchool\Api\PowerSchoolApiServiceProvider"

调试

您可以使用Ray启用调试,它将显示每个请求的原始和转换后的响应。这有助于查看来自PowerSchool的响应和GrantHolle\PowerSchool\Api\Response对象的数据。您需要安装Laravel包并启用调试

# App debug needs to be enabled also
APP_DEBUG=true

POWERSCHOOL_DEBUG=true

命令

# Fetches authorization token and caches it
php artisan powerschool:auth

API

使用外观,GrantHolle\PowerSchool\Api\Facades\PowerSchool,您可以流畅地构建PowerSchool的请求。通过提供几个关键函数的别名,您可以以适合您的方式编写请求,同时易于阅读。以下是一些相互关联的示例。请参见下面的示例,以将它们全部组合起来。

setTable(string $table)

别名:table(), forTable(), againstTable()

此操作“设置”您正在交互的表。适用于数据库扩展。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

$request = PowerSchool::table('u_my_custom_table');

setId($id)

别名:id(), forId()

设置与数据库中特定条目交互的get、put或delete请求的id。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

$request = PowerSchool::table('u_my_custom_table')->forId(100);

setMethod(string $method)

别名:usingMethod(), get(), post(), put(), patch(), delete()

设置请求的HTTP动词。当使用函数get()post()put()patch()delete()时,将自动发送请求。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

// This request is still not sent
$request = PowerSchool::table('u_my_custom_table')->setId(100)->method('get');

// This request is set to the get method and sent automatically
$response = PowerSchool::table('u_my_custom_table')->id(100)->get();
$response = PowerSchool::table('u_my_custom_table')->id(100)->get();
$response = PowerSchool::table('u_my_custom_table')->id(100)->delete();

// The above example could be rewritten like this...
$response = PowerSchool::table('u_my_custom_table')->id(100)->setMethod('get')->send();

setData(Array $data)

别名:withData(), with()

设置与请求一起发送的数据。如果是自定义表,只需发送字段及其值和与PowerSchool兼容的结构,该结构将自动构建。如果是命名查询,则只是已配置查询的args

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

$data = [
  'column_one' => 'value',
  'column_two' => 'value',
];

// Doing "table" requests, this not getting sent
$request = PowerSchool::table('u_my_custom_table')->with($data)->method('post');

// A PowerQuery (see below)
$response = PowerSchool::pq('com.organization.product.area.name')->withData($data);

setNamedQuery(string $query, Array $data = [])

别名:namedQuery(), powerQuery(), pq()

第一个参数是查询名称,遵循PowerSchool规定的约定com.organization.product.area.name。第二个参数是需要执行查询的数据,这些数据已在插件命名查询xml文件中配置。如果包含数据,则自动发送请求。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

// Will not get sent
$request = PowerSchool::powerQuery('com.organization.product.area.name');

// Gets posted automatically
$response = PowerSchool::powerQuery('com.organization.product.area.name', ['schoolid' => '100']);

setEndpoint(string $query)

别名:toEndpoint(), to(), endpoint()

设置核心PS资源的端点。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

$requestData = [
  'students' => [
    'student' => [
      'client_uid' => 100,
      'action' => 'INSERT',
      'local_id' => 100,
      'name' => [
        'first_name' => 'John',
        'last_name' => 'Doe',
      ],
      'demographics' => [
        'gender' => 'M',
        'birth_date' => '2002-08-01',
      ],
      'school_enrollment' => [
        'entry_date' => now()->format('Y-m-d'),
        'exit_date' => now()->subDays(1)->format('Y-m-d'),
        'grade_level' => 10,
        'school_number' => 100,
      ],
    ],
  ],
];

$response = PowerSchool::toEndpoint('/ws/v1/student')->with($requestData)->post();

q(string $expression)

别名:queryExpression()

q变量设置为给定的FIQL表达式。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

PowerSchool::endpoint('/ws/v1/school/3/student')
    ->q('name.last_name==Ada*')
    ->get();

adHocFilter(string $expression)

别名:filter()

为PowerQueries添加即时过滤设置$q查询变量。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

PowerSchool::pq('com.organization.plugin_name.entity.query_name')
    ->filter('number_column=lt=100')
    ->post();

adHocOrder(string $expression)

别名:order()

为PowerQueries添加即时排序设置order查询变量。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

PowerSchool::pq('com.organization.plugin_name.entity.query_name')
    ->order('students.last_name,students.first_name,students.entrydate;desc')
    ->post();

pageSize(int $pageSize)

设置pagesize查询变量。

page(int $page)

为分页设置page查询变量。

sort(string|array $columns, bool $descending = false)

设置sortsortdescending变量。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

PowerSchool::pq('com.organization.plugin_name.entity.query_name')
    ->sort('column1');

// ?sort=column1&sortdescending=false

includeCount()

包含结果中所有记录的计数。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

PowerSchool::pq('com.pearson.core.guardian.student_guardian_detail')
    ->includeCount()
    ->post();

// {
//    "name":"Students",
//    "count":707625,
//    "record":[
//       {
//          "id":3328,
//          "name":"Students",
//          ...
//       },
//       ... Only first page of actual results returned
//    ],
//    "@extensions":"activities,u_dentistry,studentcorefields,c_studentlocator"
// }

withQueryString(string|array $queryString)

别名:query()

这会将查询字符串一次性设置,而不是使用便捷方法。

projection(string|array $projection)

为请求设置projection查询变量。

excludeProjection()

别名:withoutProjection()

防止在请求中包含projection查询变量。

dataVersion(int $version, string $applicationName)

别名:withDataVersion()

设置$dataversion$dataversion_applicationname数据项。

expansions(string|array $expansions)

别名:withExpansions()

添加expansions查询变量。

extensions(string|array $expansions)

别名:withExtensions()

添加extensions查询变量。

执行请求

构建查询后,有很多执行请求的方法。最终,每个方法都在调用send()之前设置方法/HTTP动词。如果您想调用send(),请确保通过调用method(string $verb)设置方法。也有使用常量设置方法的辅助工具。

use GrantHolle\PowerSchool\Api\RequestBuilder;

RequestBuilder::GET;
RequestBuilder::POST;
RequestBuilder::PUT;
RequestBuilder::PATCH;
RequestBuilder::DELETE;

send()

使用设置的动词发送请求。默认情况下将返回查询的结果。您也可以在发送之前调用asJsonResponse()以获取Laravel的JsonResponse类的实例,这可以直接返回给客户端。

count()

在构建器上调用count()将执行计数查询,自动将/count追加到端点并执行get请求。

get(string $endpoint = null)

设置动词为get并发送请求。您也可以直接传递端点以设置端点并自动执行请求。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

PowerSchool::get('/ws/v1/staff/111');

post()

设置动词为post并发送请求。

put()

设置动词为put并发送请求。

path()

设置动词为path并发送请求。

delete()

设置动词为delete并发送请求。

getDataSubscriptionChanges(string $applicationName, int $version)

执行数据版本订阅的“增量拉取”。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

PowerSchool::getDataSubscriptionChanges('myapp', 12345);

// {
//     "$dataversion": "16323283",
//     "tables": {
//         "userscorefields": [
//             802
//         ],
//         "users": [
//             851,
//             769,
//             802,
//             112
//         ]
//     }
// } 

分页

当使用PowerQueries时,您可以使用$builder->paginate($pageSize)函数轻松分页结果。您可以在while循环中使用它,以比返回完整结果更高效的方式处理查询中的所有结果。默认页面大小为100。

use GrantHolle\PowerSchool\Api\Facades\PowerSchool;

// PowerQuery
// You have to set data in a separate function call
// Otherwise the request will be sent automatically
$builder = PowerSchool::pq('com.organization.plugin_name.entity.query_name')
    ->with(['some_variable' => $value]);
    
// "Normal" endpoint
$builder = PowerSchool::to('/ws/v1/school/1/course')
    ->method(PowerSchool::GET);
    
// "Table" endpoints    
$builder = PowerSchool::table('u_my_table')
    ->method(PowerSchool::GET);    

while ($records = $builder->paginate(25)) {
    // Do something awesome
}

响应

v3版本之前,API请求返回一个简单的stdClass实例,包含PowerSchool的原始响应。自v3版本以来,有一个新的GrantHolle\PowerSchool\Api\Response类返回,该类实现了ArrayAccess。这为您处理从PowerSchool返回的数据提供了更方便的方式。根据您发出的请求,PowerSchool返回各种键和数据嵌套。新的Response类尝试标准化返回的数据,这使得您更容易处理。

单个响应

某些响应旨在返回单个记录,例如针对/ws/contacts/contact/{id}的响应。对于这些响应,属性可以像关联数组一样访问。

$response = PowerSchool::to('/ws/contacts/contact/123')
    ->get();

// Since Response implements ArrayAccess, we can access the attributes with keys
$response['contactId']; // 123

@extensions@expansions字段解析为$extensions$expansions属性作为数组。

$response->extensions;
// [
//   "personcorefields",
// ]

列表响应

对于返回结果列表的响应,可以使用foreach迭代Response。您不需要担心属性嵌套,因为响应将从响应类型中推断出来。

$results = PowerSchool::to('/ws/v1/district/school')
    ->get();

 foreach ($results as $result) {
     // $result will be an array representing the school object returned
 }

对于get表列表,结果嵌套得有些尴尬。例如,

PowerSchool::table('u_my_table')->get();

// This returns results like
[
    [
        'id' => 1,
        'tables' => [
            'u_my_table' => [
                'column' => '',
                'column' => '',
                // etc
            ]
        ]    
    ],
    // and on and on
]

我们可以通过在Response对象上调用squashTableResponse()来减少结果的尴尬。

PowerSchool::table('u_my_table')
    ->get()
    ->squashTableResponse();

// Now the results will be simpler
[
    [
        'column' => '',
        'column' => '',
        // etc
    ],
    // and on and on
]

许可证

MIT

贡献

感谢您花时间提交问题或拉取请求。如果您是一个新功能,请尽力添加一个测试用例来覆盖该功能。然后运行

./vendor/bin/phpunit