sanity / sanity-php
Sanity API 的 PHP 库
Requires
- php: >=5.6
- guzzlehttp/guzzle: ^6.2|^7.0
Requires (Dev)
- phpunit/phpunit: ^5.7
- squizlabs/php_codesniffer: ^2.8
- dev-main
- v1.5.2
- v1.5.1
- v1.5.0
- v1.4.1
- v1.4.0
- v1.3.0
- v1.2.0
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v0.0.3
- v0.0.2
- v0.0.1
- dev-chore/php8
- dev-renovate/phpunit-phpunit-11.x
- dev-renovate/phpunit-phpunit-9.x
- dev-feat/perspectives
- dev-renovate/actions-cache-4.x
- dev-renovate/major-3-linters
- dev-renovate/ubuntu-22.x
- dev-renovate/phpunit-phpunit-8.x
- dev-renovate/phpunit-phpunit-7.x
- dev-renovate/phpunit-phpunit-6.x
- dev-renovate/phpunit-phpunit-10.x
- dev-renovate/actions-cache-3.x
- dev-renovate/configure
This package is not auto-updated.
Last update: 2024-09-26 11:38:53 UTC
README
Sanity API 的 PHP 库 Sanity API
要求
sanity-php 需要 PHP >= 5.6,并安装了 json
模块。
Composer
您可以通过 Composer 安装此库。运行以下命令
composer require sanity/sanity-php
要使用此库,请使用 Composer 的 自动加载
require_once 'vendor/autoload.php';
使用方法
实例化新的客户端
use Sanity\Client as SanityClient; $client = new SanityClient([ 'projectId' => 'your-project-id', 'dataset' => 'your-dataset-name', // Whether or not to use the API CDN for queries. Default is false. 'useCdn' => true, // If you are starting a new project, using the current UTC date is usually // a good idea. See "Specifying API version" section for more details 'apiVersion' => '2019-01-29', ]);
使用授权令牌
$client = new SanityClient([ 'projectId' => 'your-project-id', 'dataset' => 'your-dataset-name', 'useCdn' => false, 'apiVersion' => '2019-01-29', // Note that you cannot combine a token with the `useCdn` option set to true, // as authenticated requests cannot be cached 'token' => 'sanity-auth-token', ]);
指定 API 版本
Sanity 使用 UTC 时区的 ISO 日期(YYYY-MM-DD)进行版本控制。关于此的解释可以在文档中找到
通常,除非您知道要使用哪个 API 版本,否则您希望将其设置为今天的 UTC 日期。这样做可以获得所有最新的错误修复和功能,同时防止任何时区混淆并锁定 API 以防止破坏性更改。
注意:不要被诱惑使用 apiVersion
的动态值。设置静态值的原因是为了防止意外的破坏性更改。
在未来的版本中,将需要指定 API 版本。目前,为了保持向后兼容性,不指定版本将触发弃用警告并回退到使用 v1
。
通过 ID 获取单个文档
$document = $client->getDocument('someDocumentId');
执行查询
$results = $client->fetch( '*[_type == $type][0...3]', // Query ['type' => 'product'] // Params (optional) ); foreach ($product in $results) { echo $product['title'] . '\n'; }
有关如何编写查询的更多信息,请参阅 查询文档
使用视角
可以使用 perspective
选项为查询指定特殊的过滤行为。默认值是 raw
,这意味着不应用任何特殊过滤,而 published
和 previewDrafts
可以用于针对特定用例进行优化。
published
当您想确保在生产中不返回草稿文档时很有用。与私有数据集配合良好。
对于一个看起来像这样的数据集
[ { "_type": "author", "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", "name": "George Martin" }, { "_type": "author", "_id": "drafts.ecfef291-60f0-4609-bbfc-263d11a48c43", "name": "George R.R. Martin" }, { "_type": "author", "_id": "drafts.f4898efe-92c4-4dc0-9c8c-f7480aef17e2", "name": "Stephen King" } ]
和一个像这样的查询
$client = new SanityClient([ // ...config... 'useCdn' => true, 'perspective' => 'published', ]); $authors = $client->fetch('*[_type == "author"]');
那么 $authors
将只包含没有在它们的 _id
中具有 drafts.
前缀的文档,在这种情况下只是 "George Martin"。
[ { "_type": "author", "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", "name": "George Martin" } ]
previewDrafts
旨在帮助回答“在所有草稿文档发布后,我们的应用程序将是什么样子?”的问题。
给定一个像这样的数据集
[ { "_type": "author", "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", "name": "George Martin" }, { "_type": "author", "_id": "drafts.ecfef291-60f0-4609-bbfc-263d11a48c43", "name": "George R.R. Martin" }, { "_type": "author", "_id": "drafts.f4898efe-92c4-4dc0-9c8c-f7480aef17e2", "name": "Stephen King" }, { "_type": "author", "_id": "6b3792d2-a9e8-4c79-9982-c7e89f2d1e75", "name": "Terry Pratchett" } ]
和一个像这样的查询
$client = new SanityClient([ // ...config... 'useCdn' => false, // the `previewDrafts` perspective requires this to be `false` 'perspective' => 'previewDrafts', ]); $authors = $client->fetch('*[_type == "author"]');
然后 authors
将看起来像这样。请注意,结果去除了具有偏好的草稿版本的文档
[ { "_type": "author", "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", "_originalId": "drafts.ecfef291-60f0-4609-bbfc-263d11a48c43", "name": "George R.R. Martin" }, { "_type": "author", "_id": "f4898efe-92c4-4dc0-9c8c-f7480aef17e2", "_originalId": "drafts.f4898efe-92c4-4dc0-9c8c-f7480aef17e2", "name": "Stephen King" }, { "_type": "author", "_id": "6b3792d2-a9e8-4c79-9982-c7e89f2d1e75", "_originalId": "6b3792d2-a9e8-4c79-9982-c7e89f2d1e75", "name": "Terry Pratchett" } ]
由于查询模拟发布草稿后的结果,因此 _id
不包含 drafts.
前缀。如果您想检查文档是否为草稿,可以使用 _originalId
字段,该字段仅在使用 previewDrafts
视角时可用。
$authors = $client->fetch('*[_type == "author"]{..., "status": select( _originalId in path("drafts.**") => "draft", "published" )}');
这将使结果变为
[ { "_type": "author", "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", "_originalId": "drafts.ecfef291-60f0-4609-bbfc-263d11a48c43", "name": "George R.R. Martin", "status": "draft" }, { "_type": "author", "_id": "f4898efe-92c4-4dc0-9c8c-f7480aef17e2", "_originalId": "f4898efe-92c4-4dc0-9c8c-f7480aef17e2", "name": "Stephen King", "status": "published" } ]
创建文档
$doc = [ '_type' => 'bike', 'name' => 'Bengler Tandem Extraordinaire', 'seats' => 2, ]; $newDocument = $client->create($doc); echo 'Bike was created, document ID is ' . $newDocument['_id'];
这会创建一个新的文档,并具有给定的属性。它必须包含一个 _type
属性,可能 包含一个 _id
属性。如果指定了一个ID并且已经存在具有该ID的文档,则该更改将失败。如果没有指定ID,它将自动生成,并包含在返回的文档中。
创建文档(如果不存在)
如上所述,当调用 create()
并包含一个 _id
属性时,如果该ID的文档已经存在,它将失败。如果您想忽略如果它存在则创建操作,可以使用 createIfNotExists()
。它接受与 create()
相同的参数,唯一的区别是它 需要 一个 _id
属性。
$doc = [ '_id' => 'my-document-id', '_type' => 'bike', 'name' => 'Amazing bike', 'seats' => 3, ]; $newDocument = $client->createIfNotExists($doc);
替换文档
如果您不关心文档是否已经存在,只想替换它,可以使用 createOrReplace()
方法。
$doc = [ '_id' => 'my-document-id', '_type' => 'bike', 'name' => 'Amazing bike', 'seats' => 3, ]; $newDocument = $client->createOrReplace($doc);
修补/更新文档
use Sanity\Exception\BaseException; try { $updatedBike = $client ->patch('bike-123') // Document ID to patch ->set(['inStock' => false]) // Shallow merge ->inc(['numSold' => 1]) // Increment field by count ->commit(); // Perform the patch and return the modified document } catch (BaseException $error) { echo 'Oh no, the update failed: '; var_dump($error); }
待办事项:记录所有修补操作
删除文档
use Sanity\Exception\BaseException; try { $client->delete('bike-123'); } catch (BaseException $error) { echo 'Delete failed: '; var_dump($error); }
事务中的多个更改
$namePatch = $client->patch('bike-310')->set(['name' => 'A Bike To Go']); try { $client->transaction() ->create(['name' => 'Bengler Tandem Extraordinaire', 'seats' => 2]) ->delete('bike-123') ->patch($namePatch) ->commit(); echo 'A whole lot of stuff just happened!'; } catch (BaseException $error) { echo 'Transaction failed:'; var_dump($error); }
无客户端修补和事务
use Sanity\Patch; use Sanity\Transaction; // Patches: $patch = new Patch('<documentId>'); $patch->inc(['count' => 1])->unset(['visits']); $client->mutate($patch); // Transactions: $transaction = new Transaction(); $transaction ->create(['_id' => '123', 'name' => 'FooBike']) ->delete('someDocId'); $client->mutate($transaction);
关于这种方法的一个重要注意事项是,您不能在通过这种方式实例化的事务或修补上调用 commit()
,相反,您必须将它们传递给 client.mutate()
。
上传图像资产(从本地文件)
$asset = $client->uploadAssetFromFile('image', '/some/path/to/image.png'); echo $asset['_id'];
上传图像资产(从字符串)
$image = file_get_contents('/some/path/to/image.png'); $asset = $client->uploadAssetFromString('image', $buffer, [ // Will be set in the `originalFilename` property on the image asset // The filename in the URL will still be a hash 'filename' => 'magnificent-bridge.png' ]); echo $asset['_id'];
上传图像,提取EXIF和调色板数据
$asset = $client->uploadAssetFromFile('image', '/some/path/to/image.png', [ 'extract' => ['exif', 'palette'] ]); var_dump($asset['metadata']);
上传文件资产(从本地文件)
$asset = $client->uploadAssetFromFile('file', '/path/to/raspberry-pi-specs.pdf', [ // Including a mime type is not _required_ but strongly recommended 'contentType' => 'application/pdf' ]); echo $asset['_id'];
上传文件资产(从字符串)
$image = file_get_contents('/path/to/app-release.apk'); $asset = $client->uploadAssetFromString('file', $buffer, [ // Will be set in the `originalFilename` property on the image asset // The filename in the URL will still be a hash 'filename' => 'dog-walker-pro-v1.4.33.apk', // Including a mime type is not _required_ but strongly recommended 'contentType' => 'application/vnd.android.package-archive' ]); echo $asset['_id'];
引用上传的图像/文件
// Create a new document with the referenced image in the "image" field: $asset = $client->uploadAssetFromFile('image', '/some/path/to/image.png'); $document = $client->create([ '_type' => 'blogPost', 'image' => [ '_type' => 'image', 'asset' => ['_ref' => $asset['_id']] ] ]); echo $document['_id'];
// Patch existing document, setting the `heroImage` field $asset = $client->uploadAssetFromFile('image', '/some/path/to/image.png'); $updatedBike = $client ->patch('bike-123') // Document ID to patch ->set([ 'heroImage' => [ '_type' => 'image', 'asset' => ['_ref' => $asset['_id']] ] ]) ->commit();
上传图像并将其追加到数组中
$asset = $client->uploadAssetFromFile('image', '/some/path/to/image.png'); $updatedHotel = $client ->patch('hotel-coconut-lounge') // Document ID to patch ->setIfMissing(['roomPhotos' => []]) // Ensure we have an array to append to ->append('roomPhotos', [ [ '_type' => 'image', '_key' => bin2hex(random_bytes(5)), 'asset' => ['_ref' => $image['_id']] ] ]) ->commit();
获取客户端配置
$config = $client->config(); echo $config['dataset'];
设置客户端配置
$client->config(['dataset' => 'newDataset']);
新配置将合并到现有配置中,因此您只需传递您想要修改的选项。
渲染块内容
当您在Sanity中使用块编辑器时,它会生成一个结构化数组结构,您可以使用它来在任何您想要的平台渲染内容。在PHP中,一个常见的输出格式是HTML。为了使从数组结构到HTML的转换更简单,我们在库中包含了一个辅助类。
如果您的只包含基本的内置块类型,您可以通过这种方式获取渲染的HTML
use Sanity\BlockContent; $document = $client->getDocument('some-doc'); $article = $document['article']; // The field that contains your block content $html = BlockContent::toHtml($article, [ 'projectId' => 'abc123', 'dataset' => 'bikeshop', 'imageOptions' => ['w' => 320, 'h' => 240] ]);
如果您有一些自定义类型,或者想自定义渲染,您可以传递一个序列化器的关联数组
$html = BlockContent::toHtml($article, [ 'serializers' => [ 'listItem' => function ($item, $parent, $htmlBuilder) { return '<li class="my-list-item">' . implode('\n', $item['children']) . '</li>'; }, 'geopoint' => function ($item) { $attrs = $item['attributes'] $url = 'https://www.google.com/maps/embed/v1/place?key=someApiKey¢er=' $url .= $attrs['lat'] . ',' . $attrs['lng']; return '<iframe class="geomap" src="' . $url . '" allowfullscreen></iframe>' }, 'pet' => function ($item, $parent, $htmlBuilder) { return '<p class="pet">' . $htmlBuilder->escape($item['attributes']['name']) . '</p>'; } ] ]);
贡献
sanity-php
遵循 PSR-2编码风格指南。欢迎贡献,但必须符合此标准。
许可协议
MIT许可。查看LICENSE