openactive/models

用于处理Openactive规范的库

v0.27.0 2024-09-26 15:34 UTC

README

PHP版本的OpenActive机会和预订规范模型

OpenActive旨在为PHP、Ruby和.NET语言中定义的所有类提供模型文件。此存储库用于PHP文件;有关Ruby和.NET实现,请参阅Ruby.NET

目录

需求

此项目需要PHP >= 5.6。

安装

要使用Composer安装,请在终端中运行:

composer require openactive/models

使用

此包提供OpenActive规范PHP模型。

它还提供了一组schema.org规范模型。

最后,它提供了一组用于处理OpenActive的RPDE数据流的类。

模型

模型包含在\OpenActive\Models命名空间下。

您可以通过传递一个关联数组来实例化一个新的模型,其中键是属性名称,值是属性值。

例如,从您的PHP应用程序中运行:

// Make sure you use the right namespace for your models
use OpenActive\Models\OA\SessionSeries;
use OpenActive\Models\OA\Place;
use OpenActive\Models\OA\GeoCoordinates;
use OpenActive\Models\OA\Concept;
use OpenActive\Models\OA\Organization;
use OpenActive\Models\OA\Offer;

$sessionSeries = new SessionSeries([
    "name" => "Virtual BODYPUMP",
    "description" => "This is the virtual version of the original barbell class, which will help you get lean, toned and fit - fast",
    "startDate" => "2017-04-24T19:30:00-08:00",
    "endDate" => "2017-04-24T23:00:00-08:00",
    "location" => new Place([
        "name" => "Raynes Park High School, 46A West Barnes Lane",
        "geo" => new GeoCoordinates([
            "latitude" => 51.4034423828125,
            "longitude" => -0.2369088977575302,
        ])
    ]),
    "activity" => [new Concept([
        "id" => "https://openactive.io/activity-list#5e78bcbe-36db-425a-9064-bf96d09cc351",
        "prefLabel" => "Bodypump™",
        "inScheme" => "https://openactive.io/activity-list"
    ])],
    "organizer" => new Organization([
        "name" => "Central Speedball Association",
        "url" => "http://www.speedball-world.com"
    ]),
    "offers" => [new Offer([
        "identifier" => "OX-AD",
        "name" => "Adult",
        "price" => 3.3,
        "priceCurrency" => "GBP",
        "url" => "https://profile.everyoneactive.com/booking?Site=0140&Activities=1402CBP20150217&Culture=en-GB"
    ])],
]);

请注意,在创建新模型时始终存在类型强制。

例如,在上面的示例中为target属性提供string将导致抛出\OpenActive\Exception\InvalidArgumentException

为所有属性提供了一组获取器和设置器。设置器也存在类型强制。

OpenActive

OpenActive模型包含在\OpenActive\Models\OA命名空间下。

要实例化一个新的,请参阅模型部分,确保您使用模型中的正确命名空间。

Schema.org

Schema.org模型包含在\OpenActive\Models\SchemaOrg命名空间下。

要实例化一个新的,请参阅模型部分,确保您使用模型中的正确命名空间。

RPDE

RpdeItem & RpdeBody是用于生成RPDE数据页面的主要类。

数据流项

RpdeItem用于创建页面上的每个单独项目。它包括一个数据属性,它应该是OA模型的一个实例以及元数据(id、modified、state和kind)。这些模型和元数据的生成留给每个应用程序开发人员。

例如,一个会议系列集合

use OpenActive\Rpde\RpdeItem;

$feedItems = [
    new RpdeItem([
        "id" => "2",
        "modified" => 4,
        "state" => RpdeState::UPDATED,
        "kind" => RpdeKind::SESSION_SERIES,
        "data" => $sessionSeries2,
    ]),
    new RpdeItem([
        "id" => "1",
        "modified" => 5,
        "state" => RpdeState::DELETED,
        "kind" => RpdeKind::SESSION_SERIES,
    ]),
];

数据流页面

然后使用RpdeBody包装一组项目并提供RPDE页面预期的许可和下一项。为了保持页面有效并创建正确的下一链接,请使用RpdeBody::createFromNextChangeNumberRpdeBody::createFromModifiedIdRpdeItem数组创建RPDE页面数据流(构造函数已被私有化)。

RpdeBody::createFromNextChangeNumber将检查所有数据流项是否确实位于提供的$changeNumber参数之后。它将根据最新数据流的修改值和提供的$feedBaseUrl参数构建下一链接。

例如:

use OpenActive\Rpde\RpdeBody;

$feedPage = RpdeBody::createFromNextChangeNumber(
    'https://www.example.com/rpde-feeds/session-series', # $feedBaseUrl
    0, # $changeNumber,
    $feedItems
);

$feedPage->getNext(); # 'https://www.example.com/rpde-feeds/session-series?afterTimestamp=5&afterId=2'

RpdeBody::createFromModifiedId 将检查所有馈送项目是否确实在提供的 $id$modified 参数之后。它将根据最新馈送项目的 id 和修改值以及提供的 $feedBaseUrl 参数来构造下一个链接。

例如:

use OpenActive\Rpde\RpdeBody;

$feedPage = RpdeBody::createFromModifiedId(
    'https://www.example.com/rpde-feeds/session-series', # $feedBaseUrl
    0, # $modified,
    0, # $id
    $feedItems
);

$feedPage->getNext(); # 'https://www.example.com/rpde-feeds/session-series?afterChangeNumber=5'

覆盖默认许可证

$feedPage->setLicense('https://www.example.com/my-licence/v2.0');

序列化馈送页面

最后,可以使用 Serialize RpdeBody::serialize($feedPage) 来序列化馈送页面,这将还负责将每个馈送项目的数据属性序列化为 JSON-LD。

$jsonFeedPage = RpdeBody::serialize($feedPage);

有关 RPDE 馈送物的更多详细信息,请参阅 OpenActive 发布数据指南RPDE 规范

枚举

每个枚举都由一个包含每个可用值的常量的类表示。

例如,向计划中添加星期几

use OpenActive\Models\OA\Schedule;
use OpenActive\Enums\SchemaOrg\DayOfWeek;

new Schedule([
    "scheduledEventType" => "Event",
    "startTime" => "12:00:00",
    "endTime" => "14:00:00",
    "byDay" => [
        new DayOfWeek\Monday,
        new DayOfWeek\Wednesday,
        new DayOfWeek\Friday
    ],
    ...
]);

序列化

此软件包为 模型\OpenActive\Rpde\RpdeBody 对象的 JSON-LD 序列化和反序列化提供支持。

serialize($obj, $prettyPrint = false, $schema = false, $modifiers = [])

返回给定对象 $obj 的 JSON-LD 字符串表示形式。

有一个额外的参数 $prettyPrint 可以返回人类可读的 JSON-LD 字符串。

以下是一个示例,使用上面定义的 \OpenActive\Models\OA\SessionSeries

use OpenActive\Models\OA\SessionSeries;

echo SessionSeries::serialize($sessionSeries, true);

将输出

{
    "@context": [
        "https:\/\/openactive.io\/",
        "https:\/\/openactive.io\/ns-beta"
    ],
    "type": "SessionSeries",
    "name": "Virtual BODYPUMP",
    "description": "This is the virtual version of the original barbell class, which will help you get lean, toned and fit - fast.",
    "startDate": "2017-04-24T19:30:00-08:00",
    "endDate": "2017-04-24T23:00:00-08:00",
    "location": {...},
    "activity": {...},
    "organizer": {...},
    "offers": [...]
}

请注意:目前默认情况下,只有 OpenActive @context 被渲染在序列化输出中。您可以通过提供 $schema 标志来添加 Schema.org @context

deserialize($data)

从给定的 JSON-LD 表示形式返回一个对象。

$data 参数可以是 JSON-LD 字符串,也可以是关联数组,例如 json_encode($string, true) 的结果。

例如

use OpenActive\Models\OA\Action;

$jsonLd = '{"@context": ["https:\/\/openactive.io\/","https:\/\/openactive.io\/ns-beta"],"type": "Action","name": "Book","target": {"type": "EntryPoint","encodingType": "application\/vnd.openactive.v1.0+json","httpMethod": "POST","type": "EntryPoint","url": "https:\/\/example.com\/orders"}}';

$action = Action::deserialize($jsonLd);

var_dump($action);

将产生

object(OpenActive\Models\OA\Action)#3 (24) {
  ["name":protected]=>
  string(4) "Book"
  ["target":protected]=>
  object(OpenActive\Models\OA\EntryPoint)#2 (20) {
    ["encodingType":protected]=>
    string(36) "application/vnd.openactive.v1.0+json"
    ["httpMethod":protected]=>
    string(4) "POST"
    ["urlTemplate":protected]=>
    NULL
    ["actionApplication":protected]=>
    NULL
    ["application":protected]=>
    NULL
    ["actionPlatform":protected]=>
    NULL
    ["contentType":protected]=>
    NULL
    ["identifier":protected]=>
    NULL
    ["name":protected]=>
    NULL
    ["description":protected]=>
    NULL
    ["sameAs":protected]=>
    NULL
    ["url":protected]=>
    string(26) "https://example.com/orders"
    ["image":protected]=>
    NULL
    ["additionalType":protected]=>
    NULL
    ["subjectOf":protected]=>
    NULL
    ["mainEntityOfPage":protected]=>
    NULL
    ["potentialAction":protected]=>
    NULL
    ["disambiguatingDescription":protected]=>
    NULL
    ["alternateName":protected]=>
    NULL
    ["id":protected]=>
    NULL
  }
  ["result":protected]=>
  NULL
  ["startTime":protected]=>
  NULL
  ["actionStatus":protected]=>
  NULL
  ["agent":protected]=>
  NULL
  ["endTime":protected]=>
  NULL
  ["instrument":protected]=>
  NULL
  ["participant":protected]=>
  NULL
  ["object":protected]=>
  NULL
  ["error":protected]=>
  NULL
  ["location":protected]=>
  NULL
  ["identifier":protected]=>
  NULL
  ["description":protected]=>
  NULL
  ["sameAs":protected]=>
  NULL
  ["url":protected]=>
  NULL
  ["image":protected]=>
  NULL
  ["additionalType":protected]=>
  NULL
  ["subjectOf":protected]=>
  NULL
  ["mainEntityOfPage":protected]=>
  NULL
  ["potentialAction":protected]=>
  NULL
  ["disambiguatingDescription":protected]=>
  NULL
  ["alternateName":protected]=>
  NULL
  ["id":protected]=>
  NULL
}

修改器

修饰符允许您在库标准化之后更改序列化的上下文。一个用例示例是如果您正在与一个不完全遵循规范或具有其他实施细节的第三方合作,这些细节需要非标准的序列化。例如,如果第三方需要不同的日期格式,您可以这样做

use OpenActive\Models\OA\SessionSeries;

echo SessionSeries::serialize($sessionSeries, true, false, [
    function ($class, $key, $value, $object) {
      if (!in_array($key, ['startDate', 'endDate'])) {
        return $value;
      }
      return (new \DateTime($value))->format('Y.m.d.H:i:s');
    }
]);

给定的修饰符 必须 遵循此方法签名

function (string $class, string $key, mixed $value, mixed $object): mixed

每个修饰符 必须 总是响应值,因为修饰符总是被应用。如果它没有返回值,则序列化期间将清除对象中的所有数据。您 应该 使用 $class$key 参数来确定修饰符是否应该为参数运行,如果不需要,则简单地返回 $value。对于需要从父对象获取更多信息的功能,还提供了 $object 参数。

修饰符也可以添加到反序列化过程中,并在设置属性之前应用。这在库发生变化时处理迁移路径或修复来自不兼容卖家的数据时非常有用。基于前面的示例,如果在这种情况下第三方发送的日期格式很奇怪,您可以这样做

use OpenActive\Models\OA\SessionSeries;

$session = SessionSeries::deserialize('{...}', [
    function ($class, $key, $value, $object) {
      if (!in_array($key, ['startDate', 'endDate'])) {
        return $value;
      }
      return \DateTime::createFromFormat('Y.m.d.H:i:s', $value, new \DateTimeZone('Europe/London'));
    }
]);

示例和辅助修饰符可以在 src/Modifiers 目录中找到。

贡献

安装

请注意:需要 Composer 来管理依赖关系。

git clone git@github.com:openactive/models-php.git
cd models-php
composer install

运行测试

使用 PHPUnit 来运行测试。

要运行整个测试套件

./vendor/bin/phpunit

如果您想以详细模式运行整个测试套件

./vendor/bin/phpunit --verbose

您还可以通过指定要执行测试的类的相对路径来运行测试套件的一部分

./vendor/bin/phpunit --verbose tests/Unit/RpdeTest.php

有关 PHPUnit 可用的命令的更多信息,请参阅 其文档

更新模型

请参考UPDATING.md以获取指南。

实现API

这些模型可以在实现数据API的上下文中使用。请参考IMPLEMENTING_APIS.md以获取指南。