storyblok/php-client

Storyblok 客户端,轻松调用发布 API

v2.6.3 2024-03-15 17:58 UTC

README

Storyblok Logo

Storyblok PHP 客户端

这是官方的 Storyblok PHP 客户端,可以轻松访问内容交付 API 和管理 API。

Join the Storyblok Discord Community Follow @Storyblok
Follow @Storyblok

🚀 使用方法

使用 Storyblok PHP 客户端,您可以集成两种 Storyblok API

  • 管理 API:通常用于管理数据,例如创建数据、块、设置等。
  • 内容交付 API:通常用于检索数据,例如当您想要构建公共 Web 应用程序时。

在本 README 文件中,您将找到有关使用 Storyblok PHP 客户端的信息,例如

安装 Storyblok PHP 客户端

您可以通过 composer 安装 Storyblok PHP 客户端。Storyblok 的 PHP 客户端需要 PHP 版本 7.3 到 8.3。建议使用 PHP 的活跃支持版本(8.2 和 8.3)。

如果您想安装 Storyblok PHP 客户端的稳定版本,可以运行

composer require storyblok/php-client

如果您想安装当前的开发版本,可以添加版本 dev-master

composer require storyblok/php-client dev-master

执行上述命令需要您在开发环境中安装 composer。如果您需要安装 Composer,可以按照官方 Composer 文档进行操作

我们建议使用最新的 PHP 版本。

管理 API

Storyblok\ManagementClient 实例

现在我们将看到如何使用您的个人 OAuth 令牌初始化 Storyblok 管理客户端,用于 管理 API](https://www.storyblok.com/docs/api/management)。个人 OAuth 令牌可以从“我的账户”部分获取。此令牌用于读取和写入操作。用于使用管理 API 的类是 Storyblok\ManagementClient 类。当您创建一个新的 ManagementClient 对象时,可以使用个人 OAuth 令牌作为参数。

<?php
// Require composer autoload
require 'vendor/autoload.php';
// Use the Storyblok\ManagementClient class
use Storyblok\ManagementClient;
// Use the ManagementClient class
$managementClient = new ManagementClient('your-storyblok-oauth-token');

现在,您有 ManagementClient 对象($managementClient),您可以开始管理您的 Storyblok 数据。

检索数据,get() 方法

如果您需要检索数据,您必须执行一个使用 GET 方法的 HTTP 请求。ManagementClient 提供了一个 get() 方法来执行 HTTP 请求。必需的参数是 API 的路径(例如 spaces/<yourSpaceId/stories)。路径定义了您要使用哪个端点。

检索故事列表

$spaceId = 'YOUR_SPACE_ID';
$result = $managementClient->get('spaces/' . $spaceId . '/stories')->getBody();
print_r($result['stories']);

使用 getBody() 方法,您可以访问响应体,然后访问 stories 键,以访问故事列表。

创建数据,post() 方法

如果您需要创建数据,您必须执行一个使用 POST 方法的 HTTP 请求。ManagementClient 提供了一个 post() 方法来执行 HTTP 请求。必需的参数是 API 的路径(例如 spaces/<yourSpaceId/stories/)和 Story 负载数据。例如创建一个新故事:

$spaceId = 'YOUR_SPACE_ID';
$story = [
    "name" => "New Page",
    "slug" => "page-1",
    "content" =>  [
        "component" =>  "page",
        "body" =>  []
    ]
];
$result = $managementClient->post(
    'spaces/' . $spaceId . '/stories/',
    [ 'story' => $story ]
    )->getBody();
print_r($result);

更新数据,put() 方法

如果您需要更新数据,您必须使用 PUT 方法执行 HTTP 请求。ManagementClient 提供了一个 put() 方法来执行 HTTP 请求。必填参数是 API 的路径(例如 spaces/<yourSpaceId/stories/<storyId>),以及故事的有效负载。对于更新故事:

$spaceId = 'YOUR_SPACE_ID';
$storyId= 'theStoryId';
$story = [
    "name" => "Update Home Page"
];
$result = $managementClient->put(
    'spaces/' . $spaceId . '/stories/' . $storyId,
    [ 'story' => $story ]
    )->getBody();
print_r($result);

删除数据,delete() 方法

如果您需要删除数据,您必须使用 DELETE 方法执行 HTTP 请求。ManagementClient 提供了一个 delete() 方法来执行 HTTP 请求。必填参数是 API 的路径,它还定义了您想要删除的条目的标识符(例如 spaces/<yourSpaceId/stories/<storyId>)。对于删除故事:

$spaceId = 'YOUR_SPACE_ID';
$storyId = 'YOUR_STORY_ID';
$result = $managementClient->delete('spaces/' . $spaceId . '/stories/' . $storyId)->getbody();
print_r($result);

在其他区域创建的空间用于管理 API

当创建空间时,您可以选择 EU、US、CA 或 AP 区域。默认区域是 EU。

EU: api.storyblok.com
US: api-us.storyblok.com
CA: api-ca.storyblok.com
AP: api-ap.storyblok.com

例如:如果您想访问在 US 区域创建的空间,您需要将 apiEndpoint 参数定义为 api-us.storyblok.com,并强制使用 HTTPS 协议的 ssl 选项。

use Storyblok\ManagementClient;

$client = new ManagementClient(
    apiKey: 'your-storyblok-oauth-token',
    apiEndpoint: "api-us.storyblok.com",
    ssl : true
);

现在您有了 Storyblok\ManagementClient 实例,您可以从头开始管理数据。

内容分发 API

Storyblok\Client 实例

现在我们将看到如何使用访问令牌初始化 Storyblok 客户端类以消费 内容分发 API V2。您可以从“设置 > 访问令牌”选项卡(在 Storyblok UI 中的空间内)获取访问令牌。

<?php
// Require composer autoload
require 'vendor/autoload.php';
// Use the Storyblok\Client class
use Storyblok\Client;
// Use the Client class
$client = new Client('your-storyblok-readonly-accesstoken');

如果您想使用别名来引用 Storyblok\Client 类,您可以使用 use ... as ... 语句

require 'vendor/autoload.php';
use Storyblok\Client as StoryblokClient;
// Use the Storyblok\Client class via alias
$client = new StoryblokClient('your-storyblok-readonly-accesstoken');

使用其他区域创建的空间

当您创建空间时,您可以选择区域:EU、US、CA 或 AP。

例如:如果您想访问在 US 区域创建的空间,您需要将 apiRegion 参数定义为 us 值(或 US)。

use Storyblok\Client;

$client = new Client(
    apiKey: 'your-storyblok-readonly-accesstoken',
    apiRegion: 'us'
);

如果您仍在使用 PHP 7.x,您必须使用旧版语法(不带命名参数)。

use Storyblok\Client;
$client = new Client(
    'your-storyblok-readonly-accesstoken',
    null,
    'v2',
    false,
    'us'
);

现在您有了 Storyblok\Client 实例,您可以从头开始消费数据。

通过 slug 加载故事

require 'vendor/autoload.php';
use Storyblok\Client as StoryblokClient; // you can use also an alias
$client = new StoryblokClient('your-storyblok-readonly-accesstoken');
$data = $client->getStoryBySlug('home')->getBody();
// access to the body response...
print_r($data["story"]);
echo $data["cv"] . PHP_EOL;
print_r($data["rels"]);
print_r($data["links"]);

通过特定语言加载 story

如果您正在使用 字段级翻译,您可以通过 language() 方法检索特定语言的 story。语言方法需要一个字符串参数,包含语言的代码。

require 'vendor/autoload.php';
use Storyblok\Client;
$client = new Client('your-storyblok-readonly-accesstoken');
$client->language('it');
$data = $client->getStoryBySlug('home')->getBody();
// access to the body response...
print_r($data["story"]);

加载空间信息

如果您需要访问一些空间信息,如空间标识符、空间名称、最新版本的时间戳或配置的语言列表,您可以使用 spaces 端点。

<?php

require 'vendor/autoload.php';

use Storyblok\Client as StoryblokClient; // you can use also an alias

$client = new StoryblokClient('your-storyblok-readonly-accesstoken');
$space = $client->get('spaces/me/' , $client->getApiParameters());
$data = $space->getBody();
print_r($data);
// Array of the language codes:
print_r($data["space"]["language_codes"]);
// The latest version timestamp:
echo "Last timestamp : " . $data["space"]["version"] . PHP_EOL;
// The space name:
echo "Space name : " . $data["space"]["name"] . PHP_EOL;
// The space id:
echo "Space id : " . $data["space"]["id"] . PHP_EOL;

因为当前版本的 PHP 客户端没有提供从空间端点检索数据的辅助程序,您可以使用 get() 方法访问内容分发 API 的 spaces/me 路径。您需要记住的是,为 get() 方法设置第二个参数时注入 API 参数。即使您没有设置任何参数,您也必须将 getApiParameters() 作为第二个参数发送给 get() 方法,因为 PHP 客户端为您管理一些核心参数,如令牌。这是因为您正在使用低级方法 get()

通过 UUID 加载故事

require 'vendor/autoload.php';
use Storyblok\Client as StoryblokClient; // you can use also an alias
$client = new StoryblokClient('your-storyblok-readonly-accesstoken');
$client->getStoryByUuid('0c092d14-5cd4-477e-922c-c7f8e330aaea');
$data = $client->getBody();

getStoryByUuid() 方法的 getBody() 返回的数据结构与 getStoryBySlug() 的结构相同,因此:storycvrelslinks

加载故事列表

如果您需要检索故事列表,可以使用 getStories() 方法。您可以使用参数来筛选故事。例如,如果您想检索特定文件夹的所有条目,可以按以下方式使用 starts_with 选项

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');
// Get all Stories from the article folder
$client->getStories(['starts_with' => 'article']);
$data = $client->getBody();
print_r($data["stories"]);
echo $data["cv"] . PHP_EOL;
print_r($data["rels"]);
print_r($data["links"]);

在内部,starts_with 选项通过 full_slug 来过滤条目。

加载所有条目

由于 Storyblok API 的响应可能是分页的,您应该遍历所有页面以收集所有条目。Storyblok PHP 客户端提供了一个名为 getAll() 的辅助工具,用于检索所有条目。在内部,getAll() 方法根据分页数据(总条目数、每页条目数等)执行所有 API 调用。

例如,检索所有故事

$client = new Client('your-storyblok-readonly-accesstoken');
$options = $client->getApiParameters();
$options['per_page'] = 3;
$stories = $client->getAll('stories/', $options);

如果您想获取每次调用的响应数组

$client = new Client('your-storyblok-readonly-accesstoken');
$options = $client->getApiParameters();
$options['per_page'] = 3;
$response = $client->getAll('stories/', $options, true);

加载数据源条目列表

使用 Storyblok\Client,您还有一个 getDatasourceEntries() 方法来检索数据源的键/值列表

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');
// Get category entries from datasource
$client->getDatasourceEntries('categories');
// will return as ['name']['value'] Array for easy access
$nameValueArray = $client->getAsNameValueArray();
// instead, if you want to retrieve the whole response, you can use getBody() method:
$data = $client->getBody();

如果您想在一个数据源条目中除了默认值之外还接收维度值,可以在调用 getDatasourceEntries() 方法时使用 dimension 选项。您可以在使用数据源存储值列表并希望对值进行翻译时使用维度。在这种情况下,您应该为每种语言创建一个维度。

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');
// Get product entries with dimension 'de-at'
$client->getDatasourceEntries('products', ['dimension'=> 'de-at']);
// show the dimension values:
foreach ($client->getBody()['datasource_entries'] as $key => $value) {
    echo $value['dimension_value'] . PHP_EOL;
}

加载标签列表

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');
// Get all Tags
$client->getTags();
// will return the whole response
$data = $client->getBody();
// will return as ['tagName1', 'tagName2'] Array for easy access
$stringArray = $client->getAsStringArray();

访问响应头

当您对内容交付 API 进行请求时,您可以访问 HTTP 响应的头。例如,在您调用 getStories() 方法(用于检索故事列表)之后,您可以通过 getHeaders() 方法访问 HTTP 响应头。

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');
$result = $client->getStories();
$headersData = $client->getHeaders();
print_r($headersData);

检索草稿或已发布内容

在一个查询字符串可用的 Web 应用程序中,内容交付客户端会自动检查 GET 参数。

  • 使用 _storyblok 获取特定故事的草稿版本
  • 使用 _storyblok_published 来清除缓存。

如果您想覆盖此“默认”行为,或者您处于非 Web 环境中(例如,您正在实现一个命令行工具),要检索草稿内容(例如尚未发布的文章),您必须使用 editMode() 方法。如果您想检索发布的内容(例如已发布的文章),您必须使用带有 false 参数的 editMode(false) 方法。

require 'vendor/autoload.php';
use Storyblok\Client as StoryblokClient; // you can use also an alias
$client = new StoryblokClient('your-storyblok-readonly-accesstoken');
$client->editMode(); // forcing draft mode
$data = $client->getStoryBySlug('home')->getBody();
// access to the body response...
print_r($data["story"]);
echo $data["cv"] . PHP_EOL;
print_r($data["rels"]);
print_r($data["links"]);

管理缓存

当您执行 API 请求时,您可以使用 Storyblok PHP 客户端提供的缓存机制。在初始化 Storyblok\Client 时,您可以设置缓存提供者。例如,使用 setCache() 方法,您可以定义提供者(例如文件系统)和选项数组。如果您使用文件系统作为缓存项的存储,您可以使用 path 选项设置路径。

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');
$client->setCache('filesystem', [ 'path' => 'cache']);
$result = $client->getStories();
print_r($result);

您可以通过 default_lifetime 选项为缓存设置 TTL 值。

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');
$client->setCache('filesystem',
    [
        'path' => 'cache',
        'default_lifetime' => 3600
    ]);
$result = $client->getStories();
print_r($result);

缓存机制使用底层的 Symfony Cache 包。因此,您可以使用 Symfony Cache 支持的适配器。例如,如果您想使用 MySQL 数据库作为缓存存储,您可以通过 PHP PDO 类设置连接。

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');
$pdo = new PDO('mysql:host=127.0.0.1;dbname=db_php-client;charset=utf8mb4;', "root");
$client->setCache('mysql', ['pdo' => $pdo]);
$result = $client->getStories();
print_r($result);

清除缓存(如果使用 setCache)

为了在用户点击发布时清除缓存,您需要在 JavaScript 中监听发布事件或在空间设置中定义一个清除您服务器上缓存的 webhook。

<script type="text/javascript" src="//app.storyblok.com/f/storyblok-latest.js"></script>
<script type="text/javascript">
    storyblok.init()

    storyblok.on('published', function() {
        $.ajax({
            url: '/clear.php'
        })
    })
</script>

在 clear.php 中

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');
$client->setCache('filesystem', array('path' => 'cache'));
// Flush the whole cache when a story has been published
$client->flushCache();
// Or empty the cache for one specific item only
$client->deleteCacheBySlug('home');

生成导航树

$tree = $client->editMode()->getLinks()->getAsTree();

echo '<ul>';
foreach ($tree as $item) {
    echo '<li>' . $item['item']['name'];

    if (!empty($item['children'])) {
        echo '<ul>';
        foreach ($item['children'] as $item2) {
            echo '<li>' . $item2['item']['name'] . '</li>';
        }
        echo '</ul>';
    }

    echo '</li>';
}
echo '</ul>';

Nginx SSI - 服务器端包含

如果您启用了 Nginx SSI 并在使用 _editable html 注释时遇到问题,请使用以下脚本: https://gist.github.com/DominikAngerer/ca61d41bae3afcc646cfee286579ad36

关系和链接解析

为了解析关系,您可以使用客户端的 resolveRelations 方法,并传递以逗号分隔的字段列表

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');

$client->resolveRelations('component_name1.field_name1,component_name2.field_name2')
$client->getStoryBySlug('home');

另一个示例

use Storyblok\Client;
$client = new Client('your-storyblok-readonly-accesstoken');
$client->resolveRelations('popular-articles.articles');
$result = $client->getStoryBySlug("home")->getBody();

为了解析链接,您可以使用resolveLinks方法,传入您想要执行的具体解析类型,包括urlstorylink

$client = new \Storyblok\Client('your-storyblok-readonly-accesstoken');

$client->resolveLinks('url')
$client->getStoryBySlug('home');

当使用CDN API V1时,您无法解析已解析条目的关系,并且已解析的条目被注入到关系的字段中。链接解析也是同样的情况。当使用CDN API V2时,您还可以解析已解析条目中的嵌套关系(只有两层深),但已解析的条目不会被注入到字段中,而是插入到根对象中的名为rels的数组中。已解析的链接将被放置在名为links的数组中。如果您正在使用API V2,为了与API V1保持一致的行为,此客户端会为您将已解析的条目和链接注入到字段中。

代码质量

该包包含测试和代码格式化的工具

composer run all-check

该命令执行

  • vendor/bin/php-cs-fixer fix
  • vendor/bin/pest

🔗 相关链接

ℹ️ 更多资源

支持

贡献

请参阅我们的贡献指南和我们的行为准则。本项目使用semantic-release通过使用提交消息来生成新版本,我们使用Angular Convention来命名提交。有关这方面的信息,请查看semantic-release FAQ中的这个问题

许可证

此存储库在MIT许可证下发布。