bedita/php-sdk

BEdita PHP SDK

v3.1.0 2024-09-16 09:34 UTC

This package is auto-updated.

Last update: 2024-09-16 09:35:11 UTC


README

BEdita PHP 官方 PHP SDK

Github Actions PHP Code Coverage phpstan psalm Scrutinizer Code Quality Version License

先决条件

安装

要安装此库的最新版本,请运行以下命令

composer require bedita/php-sdk

基本用法

初始化 BEditaClient

使用 API URL 和 API 密钥实例化 BEditaClient。这通常通过工厂方法,如 ApiclientProvider::getApiClient() 完成,该工厂方法将从环境变量和/或配置文件中读取。

    $apiUrl = 'http://your-api-url';
    $apiKey = 'your-api-key';
    /** @var \BEdita\SDK\BEditaClient $client */
    $client = new BEditaClient($apiUrl, $apiKey);

初始化日志记录器以进行自定义日志记录

您可以使用 initLogger() 方法激活详细请求/响应日志记录到 API 调用的文件。这也通常由工厂方法,如 ApiclientProvider::getApiClient() 执行。

   $client->initLogger(['log_file' => '/path/to/file/name.log']);

请求头

某些头在 API 调用中默认处理

  • Acceptapplication/vnd.api+json 为格式使用 JSON-API
  • Content-Type 在设置请求体时为 application/json
  • Authorization 使用 Bearer {token},如果设置了 JWT 令牌
  • X-Api-Key 使用传递给构造函数的密钥

在每次 API 调用中,您都可以在 $header 数组参数中添加新头或覆盖默认值(见下文)。

认证和令牌

要检索或设置 JWT 令牌,您可以使用

  • authenticate(string $username, string $password) 方法执行经典的用户名/密码认证
  • 使用 setupTokens() 设置 JWT 令牌,从之前的 authenticate 或其他方法检索,用于后续调用
    $response = (array)$client->authenticate('my-username', 'my-password');
    if (!empty($response['meta'])) {
        $client->setupTokens($response['meta']);
    }

在每次后续 API 调用中,JWT 令牌将在 Authentication 头中使用,并且 SDK 将自动通过刷新令牌处理过期令牌响应。

直接 API 调用和实用方法

为了使用 BEdita 4 API,您通常有两种选择

  1. 使用直接 API 调用,调用 POST/GET/PATCH/DELETE HTTP 方法,使用对应的 get()/post()/patch()/delete() 方法,确保路径、查询字符串、正文和头正确填充;
  2. 使用以下实用方法,如 saveaddRelated 等,以简化设置并获得更清晰的代码。

读取对象和资源

您可以使用 getObjects(string $type = 'objects', ?array $query = null, ?array $headers = null) 通过类型检索对象列表,使用 getObject(int|string $id, string $type = 'objects', ?array $query = null, ?array $headers = null) 通过唯一标识符和类型获取单个对象。

示例

    // get documents
    $response = (array)$client->getObjects('documents'); // argument passed is a string $type

    // get documents using a filter
    $query = [
        'filter' => ['parent' => 'some-parent-id'],
    ];
    $response = (array)$client->getObjects('documents', $query); // arguments passed are string $type and array $query

    // get documents using a filter and more query options
    // include: including related data by relations "has_media" and "part_of"
    // lang: the desired lang (if translation is available)
    $query = [
        'filter' => ['parent' => 'some-parent-id'],
        'include' => 'has_media,part_of',
        'lang' => 'en',
    ];
    $response = (array)$client->getObjects('documents', $query); // arguments passed are string $type and array $query
    // get document 17823
    $response = (array)$client->getObject(17823, 'documents'); // arguments passed are int|string $id, string $type

    // get document 17823, english version, including related data by relations "has_media" and "part_of"
    $query = [
        'lang' => 'en',
        'include' => 'has_media,part_of',
    ];
    $response = (array)$client->getObject(17823, 'documents', ['lang' => 'en_EN']); // arguments passed are int|string $id, string $type and array $query

    // get folder website-footer
    $response = (array)$client->getObject('website-footer', 'folders'); // arguments passed are int|string $id, string $type

您还可以使用 get(string $path, ?array $query = null, ?array $headers = null) 进行显式的 GET API 调用,指定完整的请求路径。这是调用特殊端点(例如,不是用于检索对象或资源的 GET 调用)的正确方式,如 /home/status

    // get API status
    $response = (array)$client->get('/status'); // argument passed is string $path

    // get API home info
    $response = (array)$client->get('/home'); // argument passed is string $path

    // get a list of documents
    $query = [
        'filter' => ['parent' => 'some-parent-id'],
    ];
    $response = (array)$client->get('/documents', $query); // arguments passed are string $path and array $query

    // get a stream by id
    $response = (array)$client->get('/streams/the-stream-id'); // argument passed is string $path

当您需要获取相关数据时,可以使用 getRelated(int|string $id, string $type, string $relation, ?array $query = null, ?array $headers = null)

    // get subfolders for a folder with ID 888
    $query = [
        'filter' => ['type' => 'folders'],
    ];
    $subfolders = $client->getRelated(888, 'folders', 'children', $query); // arguments passed are int|string $id, string $type, string $relation, array $query

    // get children (all types) inside a folder with unique name 'my-folder-uname'
    $children = $client->getRelated('my-folder-uname', 'folders', 'children'); // arguments passed are int|string $id, string $type, string $relation

保存对象和资源

您可以使用 save(string $type, array $data, ?array $headers = null) 方法:这是在 BEdita 4 中创建或更新对象或资源的标准方法。请注意,有效负载由对象属性组成,无需指定 data.attribute 部分,当处理直接 POST 或 PATCH API 调用时,您必须使用此部分。

示例

    // save a new document
    $data = [
        'title' => 'My new doc',
        'status' => 'on',
    ];
    $response = (array)$client->save('documents', $data); // arguments passed are string $type, array $data
    // retrocompatibility version with saveObject, deprecated
    $response = (array)$client->saveObject('documents', $data); // arguments passed are string $type, array $data

    // save an existing document
    $data = [
        'id' => 999,
        'title' => 'My new doc, changed title',
    ];
    $response = (array)$client->save('documents', $data); // arguments passed are string $type, array $data
    // retrocompatibility version with saveObject, deprecated
    $response = (array)$client->saveObject('documents', $data); // arguments passed are string $type, array $data

savesaveObject 在内部使用 patch(string $path, mixed $body, ?array $headers = null)(在保存现有对象时)或 post(string $path, mixed $body, ?array $headers = null)(在保存新对象时)。

如果您想直接使用它们

    // save a new document
    $data = [
        'type' => 'documents',
        'attributes' => [
            'title' => 'My doc',
            'status' => 'on',
        ],
    ];
    $response = (array)$client->post('/documents', $data); // arguments passed are string $path, array $data

    // save an existing document
    $data = [
        'type' => 'documents',
        'attributes' => [
            'title' => 'My doc',
            'status' => 'on',
        ],
    ];
    $response = (array)$client->post('/documents/999', $data); // arguments passed are string $path, array $data

删除和恢复数据

软删除

软删除将对象放入垃圾桶。您可以使用 delete(string $path, mixed $body = null, ?array $headers = null)deleteObject(int|string $id, string $type) 删除对象。

    // delete document by ID 99999
    $response = $client->delete('/documents/99999'); // argument passed is string $path

    // delete document by ID 99999 and type documents
    $response = $client->deleteObject(99999, 'documents'); // arguments passed are string|int $id, string $type

    // delete multiple
    $response = $client->deleteObjects([999991, 999992, 999993], 'documents');

恢复数据

垃圾桶中的数据可以使用 restoreObject(int|string $id, string $type) 恢复。

    // restore document 99999
    $response = $client->restoreObject(99999, 'documents'); // arguments passed are string|int $id, string $type

    // restore multiple
    $response = $client->restoreObjects([999991, 999992, 999993], 'documents');

硬删除

硬删除将对象从垃圾桶中删除。您可以使用 remove(int|string $id) 从垃圾桶中删除对象。

    // delete document by ID 99999
    $response = $client->deleteObject(99999, 'documents'); // arguments passed are string|int $id, string $type

    // permanently remove documents 99999
    $response = $client->remove(99999); // argument passed is string|int $id

    // permanently remove multiple
    $response = $client->removeObjects([999991, 999992, 999993]);

处理关系

添加相关对象

您可以使用 addRelated(int|string $id, string $type, string $relation, array $data, ?array $headers = null) 添加相关对象。

    // save a document and add related objects, in this example a "see_also" relation between documents and documents is involved
    $document = $client->save('documents', ['title' => 'My new doc']);
    $relatedData = [
        [
            'id' => 9999, // another doc id
            'type' => 'documents',
        ],
    ];
    $client->addRelated($document['data']['id'], 'documents', 'see_also', $relatedData); // arguments passed are int|string $id, string $type, string $relation, array $relationData

替换相关对象

replaceRelated(int|string $id, string $type, string $relation, array $data, ?array $headers = null) 便于替换相关对象。

    // replace related objects, in this example a "see_also" relation between document 8888 and document 9999
    $relatedData = [
        [
            'id' => 9999,
            'type' => 'documents',
        ],
    ];
    $client->replaceRelated(8888, 'documents', 'see_also', $relatedData); // arguments passed are int|string $id, string $type, string $relation, array $relationData

注意:内部 addRelated 使用 post,而 replaceRelated 使用 patch。两者都会调用 /:type/:id/relationships/:relation

删除相关对象

可以使用 removeRelated(int|string $id, string $type, string $relation, array $data, ?array $headers = null) 删除相关对象。

    // remove related data, in this example a "see_also" relation between document 8888 and document 9999
    $relatedData = [
        [
            'id' => 9999,
            'type' => 'documents',
        ],
    ];
    $client->removeRelated(8888, 'documents', 'see_also', $relatedData); // arguments passed are int|string $id, string $type, string $relation, array $relationData

上传

通过调用带有文件内容的 POST 来创建新的媒体对象,这是创建媒体对象的最简单方法。

图像上传示例

    $content = file_get_contents('/path/to/image.png');

    $response = $client->post('/images/upload/image.png',
        $content,
        ['Content-type' => 'image/png']
    );

将创建一个新的类型为 images 的对象,其中包含 image.png 文件作为相关流资源。如果您需要通过流处理更多底层操作,请阅读下面的段落。

上传流

使用 upload(string $filename, string $filepath, ?array $headers = null) 执行 POST /streams/upload/:filename 并创建一个新的流。

    // upload the image /home/gustavo/sample.jpg
    $response = $client->upload('sample.jpg', '/home/gustavo/sample.jpg');

注意:如果不传递 $headers 参数,函数将使用 mime_content_type($filepath)

    // upload the image /home/gustavo/sample.jpg, passing content type
    $response = $client->upload('sample.jpg', '/home/gustavo/sample.jpg', ['Content-type' => 'image/jpeg']);

从流创建媒体

您可以使用 createMediaFromStream(string $streamId, string $type, array $body) 从流创建媒体对象。这基本上会进行 3 次调用

  • POST /:type$body 作为有效负载,创建媒体对象
  • PATCH /streams/:stream_id/relationships/object 修改流,添加到媒体关系
  • GET /:type/:id 获取媒体数据
    // upload an audio file
    $filepath = '/home/gustavo/sample.mp3';
    $filename = basename($filepath);
    $headers = ['Content-type' => 'audio/mpeg'];
    $response = $client->upload($filename, $filepath, $headers);

    // create media from stream
    $streamId = Hash::get($response, 'data.id');
    $body = [
        'data' => [
            'type' => 'audios',
            'attributes' => [
                'title' => $filename,
                'status' => 'on',
            ],
        ],
    ];
    $response = $client->createMediaFromStream($id, $type, $body);

缩略图

可以使用 thumbs(int|null $id, $query = []) 获取媒体缩略图。

用法

    // get thumbnail for media 123 => GET /media/thumbs/123
    $client->thumbs(123);

    // get thumbnail for media 123 with a preset => GET /media/thumbs/123&preset=glide
    $client->thumbs(123, ['preset' => 'glide']);

    // get thumbnail for multiple media => GET /media/thumbs?ids=123,124,125
    $client->thumbs(null, ['ids' => '123,124,125']);

    // get thumbnail for multiple media with a preset => GET /media/thumbs?ids=123,124,125&preset=async
    $client->thumbs(null, ['ids' => '123,124,125', 'preset' => 'async']);

    // get thumbnail media 123 with specific options (these options could be not available... just set in preset(s)) => GET /media/thumbs/123/options[w]=100&options[h]=80&options[fm]=jpg
    $client->thumbs(123, ['options' => ['w' => 100, 'h' => 80, 'fm' => 'jpg']]);

模式

您可以使用 schema(string $type) 获取资源或对象的 JSON SCHEMA。

    // get schema of users => GET /model/schema/users
    $schema = $client->schema('users');

获取关系(数据、参数)的信息,并使用 relationData(string $name) 获取左右对象类型。

    // get relation data of relation see_also => GET /model/relations/see_also
    $schema = $client->relationData('see_also');