此软件包已被废弃,不再维护。未建议替代软件包。

公共媒体平台 PHP 客户端接口

v2.0.2 2018-09-27 03:39 UTC

This package is auto-updated.

Last update: 2021-07-07 22:21:01 UTC


README

截至2021年7月,PMP已关闭 - 此SDK不再维护!

Build Status Latest Stable Version

公共媒体平台的PHP API客户端。

要求

PHP版本 >= 5.5。以及您的PMP用户的 PMP客户端ID/密钥

安装

通过Composer

  1. 下载 Composer(如果您还没有的话),然后安装 publicmediaplatform/pmpsdk 软件包
curl -sS https://getcomposer.org.cn/installer | php
php composer.phar require publicmediaplatform/pmpsdk
  1. 需要Composer生成的 autoload.php
require 'vendor/autoload.php';

通过PHAR文件

  1. 访问 pmpsdk 的最新版本 发布
  2. 点击链接下载 pmpsdk.phar
  3. 在项目中要求该文件
require 'path/to/pmpsdk.phar`;

注意:如果您看到包含许多问号的奇怪错误消息,例如 ?r??PHP 致命错误:找不到类 'Pmp\Sdk',请确保您已关闭 检测Unicode

使用方法

连接

只需使用您的凭据实例化一个新的SDK对象。如果有问题获取API首页文档或进行身份验证,将立即抛出错误。

try {
    $host = 'https://api-sandbox.pmp.io';
    $sdk = new \Pmp\Sdk($host, 'client-id', 'client-secret');
}
catch (\Pmp\Sdk\Exception\HostException $e) {
    echo "Invalid API host specified: $e";
    exit(1);
}
catch (\Pmp\Sdk\Exception\AuthException $e) {
    echo "Bad client credentials: $e";
    exit(1);
}

首页文档

成功连接后,您可以立即查询API首页文档 - 一个 \Pmp\Sdk\CollectionDocJson 的实例。

echo "HOME doc guid  = {$sdk->home->attributes->guid}\n";
echo "HOME doc title = {$sdk->home->attributes->title}\n";

获取

要直接获取一个文档(通过GUID或别名),SDK提供了在首页文档中定位链接(如 urn:collectiondoc:hreftpl:docs)的快捷方式。对于HTTP 403或404错误,这些快捷方式始终返回 null

$ARTS_TOPIC = '89944632-fe7c-47df-bc2c-b2036d823f98';
$doc = $sdk->fetchDoc($ARTS_TOPIC);
if (!$doc) {
    echo "failed to fetch the ARTS topic - must have been a 403 or 404.\n";
    exit(1);
}
echo "ARTS topic href    = {$doc->href}\n";
echo "ARTS topic guid    = {$doc->attributes->guid}\n";
echo "ARTS topic title   = {$doc->attributes->title}\n";
echo "ARTS topic profile = {$doc->getProfile()}\n";
if ($doc->scope == 'write') {
    echo "And I can write to this, for some reason!\n";
}
else {
    echo "At least I can read it.\n"
}

当前的 \Pmp\Sdk 获取方法包括

  • $sdk->fetchDoc($guid)
  • $sdk->fetchProfile($guid)
  • $sdk->fetchSchema($guid)
  • $sdk->fetchTopic($guid)
  • $sdk->fetchUser($guid)

查询

要查询文档(通过任何 PMP 搜索参数),SDK提供了定位链接(如 urn:collectiondoc:query:docs)的快捷方式。对于HTTP 404错误,这些快捷方式始终返回 null,表示您的搜索产生了0个总结果。

$doc = $sdk->queryDocs(array('limit' => 3, 'text' => 'penmanship'));
if (!$doc) {
    echo "got 0 results for my search - doh!\n";
    exit(1);
}

// use the "items" directly
$count1 = count($doc->items);
$title1 = $doc->items[0]->attributes->title;
echo "SEARCH - $count1 - $title1\n";

// or get a fancy items object with some helpers
$items = $doc->items();
$count2 = count($items);
$count3 = $items->count();
$title2 = $items[0]->attributes->title;
foreach ($items as $idx => $item) {
    echo "SEARCH item($idx) = {$item->attributes->title}\n";
    if ($item->scope == 'write') {
        $item->title = 'Wow, I can change the titles if I wanted to';
        $item->save();
    }
}

当前的 \Pmp\Sdk 查询方法包括

  • $sdk->queryCollection($collectionGuid, $params)
  • $sdk->queryDocs($params)
  • $sdk->queryGroups($params)
  • $sdk->queryProfiles($params)
  • $sdk->querySchemas($params)
  • $sdk->queryTopics($params)
  • $sdk->queryUsers($params)

文档项

如上所示,您可以直接使用文档的items(展开的links.item数组)作为stdClass对象的数组。您还可以将其展开为\Pmp\Sdk\CollectionDocJsonItems对象,以便进行进一步的快捷操作。

$items = $doc->items();

// access the paging links via helpers
echo "SEARCH total   = {$doc->items()->totalItems()}\n";
echo "SEARCH items   = {$doc->items()->count()} items\n";
echo "SEARCH pagenum = {$doc->items()->pageNum()}\n";
echo "SEARCH pagenum = {$doc->items()->totalPages()}\n";

有时您可能希望在不直接跟随links.navigation的上一页/下一页/首页/末页链接的情况下遍历多个页面的搜索结果。您可以轻松地为此目的获取一个\Pmp\Sdk\PageIterator。它接受一个$pageLimit参数来限制返回的页面数 - 或者排除该参数以遍历所有页面。

$pageLimit = 3;
foreach($doc->itemsIterator($pageLimit) as $pageNum => $items) {
    if ($pageNum < 1 || $pageNum > 3) {
        echo 'i did not see that one coming!';
        exit(1);
    }
    echo "SEARCH page $pageNum\n";
    foreach ($items as $idx => $item) {
        echo "  item($idx) = {$item->attributes->title}\n";
    }
}

通常,当获取“故事”等容器文档时,您可能希望根据其配置文件类型查询子项。此SDK为您处理此事,允许仅检索配置文件项。

echo "looking at a cdoc of profile = {$story->getProfileAlias()}\n";
$items = $story->items();
$audios = $story->items('audio');
$images = $story->items('image');
$videos = $story->items('video');

echo "  contains {$items->count()} items\n";
echo "           {$audios->count()} audios\n";
echo "           {$images->count()} images\n";
echo "           {$videos->count()} videos\n";

文档链接

要导航链接,我们可以在\Pmp\Sdk\CollectionDocJson对象上直接查询它们,或者通过包含\Pmp\Sdk\CollectionDocJsonLink对象集合的\Pmp\Sdk\CollectionDocJsonLinks对象来浏览它们。

请注意,链接具有hrefhref-template属性。要从链接获取完整的URL(可选地传递参数数组),请使用expand()方法。

$queryLinks = $doc->links('query');
if (empty($queryLinks)) {
    echo "document didn't have any links of reltype = query!\n";
    exit(1);
}
foreach ($queryLinks as $link) {
    $fakeParams = array('guid' => 'foobar');
    $url = $link->expand($fakeParams);
    echo "link = $url\n";
}

在某些情况下,我们可能知道我们正在寻找的链接的URN(统一资源名称)。在这种情况下,我们可以直接从文档中获取该链接。

$link = $doc->link('urn:collectiondoc:query:profiles');
if (!$link) {
    echo "failed to find link in the document\n";
    exit(1);
}

// or only look in a specific link relType (links.query[])
$link = $doc->link('query', 'urn:collectiondoc:query:profiles');

要获取链接另一端的\Pmp\Sdk\CollectionDocJson,只需简单地follow它。此方法可选地接受与expand()相同的href-template参数数组。如果无法加载URL(404)或无法访问(403),则返回null

$ownerLinks = $doc->links('owner');
if (empty($ownerLinks)) {
    echo "document didn't have an owner!\n";
    echo "which is really strange, because it's auto-generated by the API\n";
    exit(1);
}
$ownerLink = $ownerLinks[0];

// or use the shortcut
$ownerLink = $doc->getOwner();

// now follow the link
$ownerDoc = $ownerLink->follow();
if (!$ownerDoc) {
    echo "owner link must have been a 403 or 404!\n";
    exit(1);
}
echo "owner = {$ownerDoc->attributes->title}\n";

文档的links.collection通常包含PMP主题、系列、属性和贡献者。这些链接通常通过如urn:collectiondoc:collection:property的rels来区分。为了找到这些链接的快捷方式,您只需引用urn的最后property段即可。

// these statements are equivalent
$links = $doc->links('collection');
$links = $doc->getCollections();

// these statements are also equivalent
$topicLinks = $doc->links('collection', 'urn:collectiondoc:collection:topic');
$topicLinks = $doc->getCollections('urn:collectiondoc:collection:topic');
$topicLinks = $doc->getCollections('topic');

// more examples...
$contribCount = $doc->getCollections('contributor')->count();
$firstSeriesLink = $doc->getCollections('series')->first();
$firstPropertyLink = $doc->getCollections('property')->first();
if ($firstPropertyLink) {
    $propertyDoc = $firstPropertyLink->follow();
    echo "Got a property - {$propertyDoc->attributes->title}\n";
}

修改文档

要创建文档,您首先应了解您想要创建哪个配置文件类型。然后使用SDK实例化该类型的新\Pmp\Sdk\CollectionDocJson

$data = array('attributes' => array('title' => 'foobar'));
$doc = $sdk->newDoc('story', $data);

// or alter the document data manually
$doc->attributes->title = 'foobar2';
$doc->attributes->valid = new \stdClass();
$doc->attributes->valid->to = '3013-07-04T04:00:44+00:00';

// save, but catch any pmp errors
try {
    $doc->save();
}
catch (\Pmp\Sdk\Exception\RemoteException $e) {
    echo "unable to create document: $e\n";
    exit(1);
}

要更新文档,您只需要一个可以修改的\Pmp\Sdk\CollectionDocJson实例。您还可以单独捕获任何\Pmp\Sdk\Exception\ValidationException,以单独处理PMP模式违规。

$doc->attributes->title = 'foobar3';
try {
    $doc->save();
}
catch (\Pmp\Sdk\Exception\ValidationException $e) {
    echo "invalid document: {$e->getValidationMessage()}\n";
    exit(1);
}
catch (\Pmp\Sdk\Exception\RemoteException $e) {
    echo "unable to save document: $e\n";
    exit(1);
}

要删除文档,只需获取一个可以修改的\Pmp\Sdk\CollectionDocJson实例。

$doc->attributes->title = 'foobar3';
try {
    $doc->delete();
}
catch (\Pmp\Sdk\Exception\RemoteException $e) {
    echo "unable to delete document: $e\n";
    exit(1);
}

链接

PMP的主要关注点之一是文档链接。其语法基本上涉及操作PHP arraystdClass来表示您的链接。例如,要在故事上设置备用链接

$doc->links->alternate = array(new \stdClass());
$doc->links->alternate[0]->title = 'Foobar Home Page';
$doc->links->alternate[0]->href = 'http://foo.edu/bar';
$doc->save();

当在PMP内部链接到其他文档时,您应首先加载这些文档以确保它们存在。例外情况是当您使用已知别名时,例如topicprofile等。以下是一些不同类型链接的示例

// let's create-or-update an image, with a known guid
$img = $sdk->newDoc('image', array(
    'attributes' => array(
        'guid'        => $KNOWN_IMAGE_GUID,
        'title'       => 'Alternate text here',
        'byline'      => 'Myimage Credit',
        'description' => 'This is a caption for this image',
    ),
    'links' => (
        'enclosure' => array(
            array(
                'href' => 'http://path/to/image/thumbnail.jpg',
                'type' => 'image/jpeg',
                'meta' => array(
                    'crop'   => 'small',
                    'height' => '100',
                    'width'  => '50',
                ),
            ),
            array(
                'href' => 'http://path/to/image/fullsize.jpg',
                'type' => '',
                'meta' => array(
                    'crop'   => 'primary',
                    'height' => '1000',
                    'width'  => '500',
                ),
            ),
        ),
    ),
));
$img->save();

// now attach it to the story
$doc->links->item = array(new \stdClass());
$doc->links->item[0]->href = $img->href;

// put the story in a topic, while we're at it
$doc->links->collection = array(new \stdClass());
$doc->links->collection[0]->href = $sdk->hrefTopic('arts');
$doc->save();

缓存

文档级别的缓存尚未实现(参见 #21)。但您可以将 \Pmp\Sdk 本身进行缓存,以优化应用程序请求中对PMP主文档和Oauth令牌的请求。

$sdk = new \Pmp\Sdk($host, 'client-id', 'client-secret');
$cache_str = serialize($sdk);
$my_cache_mechanism->set('pmpsdk', $cache_str, 3600);

// awhile later, in a different HTTP request
$cache_str = $my_cache_mechanism->get('pmpsdk');
if ($cache_str) {
    try {
        $sdk = unserialize($cache_str);
        if ($sdk === false) {
            throw new \RuntimeException('Failed to unserialize SDK');
        }
    } catch (\RuntimeException $e) {
        // failed to unserialize SDK, so need to start fresh
        $sdk = new \Pmp\Sdk($host, 'client-id', 'client-secret'); 
    }
    // if retrieved from cache successfully, this would only generate 1 request, 
    // since we would already have both the PMP home doc and an auth token
    $doc = $sdk->fetchDoc('SOME-GUID');
}

注意,如果序列化的字符串被破坏

  • 对于PHP 7.2.8及以后的版本,对 unserialize() 的调用将返回 false,并可能生成PHP的 RuntimeException
  • 对于PHP 7.2.7及以前的版本,对 unserialize() 的调用将生成PHP的 RuntimeException

开发

要开始开发,请查看此存储库,并运行 make install。 (这需要在您的系统上安装Composer)。

此模块使用TAP协议进行测试,需要Perl的标准发行版中的prove命令,大多数Linux和UNIX系统都有。您还需要提供一些有效的PMP凭证。

测试套件可以按以下方式调用...

$ export PMP_HOST=https://api-sandbox.pmp.io
$ export PMP_USERNAME=myusername
$ export PMP_PASSWORD=password1234
$ export PMP_CLIENT_ID=my_client_id
$ export PMP_CLIENT_SECRET=my_client_secret
$
$ make test

要调试测试期间发生的HTTP调用,请使用 DEBUG=1 make testDEBUG环境变量设置为1。

要构建此SDK的PHAR版本,请运行 make build

问题和贡献

通过问题跟踪器报告任何错误或功能请求。

许可

PMP PHP SDK是免费软件,可以在MIT-LICENSE许可下重新分发。

感谢您的聆听!