Skip to content

Releases: flyocloud/nitro-php-sdk

3.8

Choose a tag to compare

@nadar nadar released this 12 Oct 12:16
8aade3d

Generated types: constants for field options

flyo-generate-types gives every block class one constant per option of each content and config
field that has a fixed set of them, select fields included. A constant is named
<CONTENT|CONFIG>_<FIELD>_<OPTION> and holds the option exactly as Flyo lists it:

  class BlockHero extends \Flyo\Model\Block
  {
      public const IDENTIFIER = 'hero';

      public const COMPONENT = 'Hero';
+
+     public const CONTENT_SIZE_SMALL = 'small';
+     public const CONTENT_SIZE_MEDIUM = 'medium';
+     public const CONTENT_SIZE_LARGE = 'large';
+
+     public const CONFIG_THEME_LIGHT = 'light';
+     public const CONFIG_THEME_DARK = 'dark';

If two options would get the same name (Small and small), neither gets a constant and the
generator prints a warning. Numbering them instead would let a name silently move to another option
once one is added in Flyo.

This changes the generated file of every block with such a field, so --check reports them as out
of date until you regenerate once. The deprecated flyo-generate-blocks does not generate the
constants, and its output stays as it was.

Generated types: an option containing */

An option whose value contains */ closed the docblock the field's type is written into, so the
generated file did not parse. Such a field is now typed string, like a field with an option that
spans lines, and gets no constants. This applies to both commands, but only changes files that were
broken before.

What's Changed

  • Add enum constants for field options in generated block types by @nadar in #8

Full Changelog: 3.7...3.8

3.7

3.7

Choose a tag to compare

@nadar nadar released this 08 Oct 11:46
baeb387

Generated types: select fields keep their values

A select field's value is typed with the values an editor can pick again. The API lists null
among a nullable select's allowed values, and the generator used to drop the whole list because of
it, falling back to string. Its options, an empty list instead of an object when nothing is
selected, is now typed as exactly that:

  size: object{
-     value: string|null,
-     options: \stdClass|array<int, mixed>,
+     value: 'small'|'medium'|'large'|null,
+     options: \stdClass|array{},
      label: string|null
  }|null,

A match over value can be exhaustive now, and PHPStan reports a comparison against a value the
field does not have.

This changes the generated file of every block, entity and container that has a select field, so
--check reports them as out of date until you regenerate once. That includes the deprecated
flyo-generate-blocks: keeping its output byte-identical would have meant keeping the bug.

What's Changed

  • fix(generator): keep the literals of a nullable enum, type empty lists by @nadar in #7

Full Changelog: 3.6...3.7

3.6

3.6

Choose a tag to compare

@nadar nadar released this 23 Sep 09:40
3efbb97

Nothing in lib/Api or lib/Model changed and no runtime behaviour changed. The block generator
grew into a generator for every typed schema, under a new name.

New: vendor/bin/flyo-generate-types

Takes the same arguments and options as flyo-generate-blocks, but generates every kind of typed
schema the document declares, each into a sub-namespace and directory of its own:

kind directory extends narrows
blocks <target>/Blocks \Flyo\Model\Block getContent(), getConfig(), getItems()
containers <target>/Containers \Flyo\Model\ConfigResponseContainersValue getItems()
container items <target>/Containers \Flyo\Model\ContainerPage getProperties(), getChildren()
entities <target>/Entities \Flyo\Model\Entity getModel()

So <namespace> is now a root: with App/Flyo and app/Flyo, blocks land in
App\Flyo\Blocks, containers in App\Flyo\Containers and entities in App\Flyo\Entities. Like
the block classes, all of them are documentation-only; see the "Typed Schemas" section of the
README for how each one is used.

Pass --lowercase for lower-case kind directories and sub-namespaces (blocks, containers,
entities), as Yii 2 expects them: app\flyo\blocks\BlockHero in flyo/blocks/BlockHero.php,
with app/flyo as namespace and flyo as target.

A schema carrying an x-schema-type this version cannot generate yet is skipped with a warning,
so a kind added to the API later never disappears silently.

Deprecated: vendor/bin/flyo-generate-blocks

It keeps working until the next major release and keeps generating byte-identical files, so a
committed target and its --check keep passing after the upgrade. The only difference is a
deprecation warning on stderr, printed on every run, --quiet included, like every warning.

To migrate, switch the script to the new command with a root namespace. The class names are the
same, only their namespace gains the kind:

  "scripts": {
-     "flyo:types": "vendor/bin/flyo-generate-blocks <source> App/Blocks app/Blocks"
+     "flyo:types": "vendor/bin/flyo-generate-types <source> App/Flyo app/Flyo"
  }
// 3.5
/** @var \App\Blocks\BlockHero $block */

// 3.6
/** @var \App\Flyo\Blocks\BlockHero $block */

Then delete the old target directory. If you would rather keep the directory, pointing the new
command at it works too: blocks generated there by the old command carry the @generated marker
and are cleaned up, and the new command warns when the namespace you pass already ends in
Blocks, because the blocks would then land in ...\Blocks\Blocks.

Moved: the generator classes

The generator itself moved from Flyo\Blocks\Generator to Flyo\Generator. Those classes are
the internals of the two binaries and were never documented. Of the old namespace, only
\Flyo\Blocks\Generator\Cli::main() remains, deprecated, as the entry point of
flyo-generate-blocks. If you called any other class of it directly, call
\Flyo\Generator\Cli::main() or the binary instead.

Full Changelog: 3.5...3.6

3.5

3.5

Choose a tag to compare

@nadar nadar released this 17 Sep 10:22

Generated against OpenAPI spec 2.45 (was 2.44).

The 404 body of the entity endpoints is now EntityNotFoundResponse

EntitiesApi::entityByUniqueid() and EntitiesApi::entityBySlug() both answer a 404 with the same
body, so the schema was renamed from entityByUniqueid_404_response to entityNotFoundResponse.
The model is unchanged field for field — name, message, status, entity_unique_id, href —
only the class name moved:

// 3.3
/** @var \Flyo\Model\Entity|\Flyo\Model\EntityByUniqueid404Response $result */

// 3.4
/** @var \Flyo\Model\Entity|\Flyo\Model\EntityNotFoundResponse $result */
$result = (new \Flyo\Api\EntitiesApi())->entityByUniqueid($uniqueidOrDraftToken);

if ($result instanceof \Flyo\Model\EntityNotFoundResponse) {
    $href = $result->getHref(); // where it lives now, or null
}

\Flyo\Model\EntityByUniqueid404Response still exists and is now a deprecated subclass of
EntityNotFoundResponse, so nothing fails to autoload and anything you built against the old
class still passes where the new one is expected. It will be removed in a future major release.

One thing to fix while upgrading: the endpoints now return an EntityNotFoundResponse, which is
the parent class, so instanceof \Flyo\Model\EntityByUniqueid404Response checks and parameter
types hinting the old class no longer match the returned object. Replace those with
EntityNotFoundResponse. Reading the response — getters, array access, json_encode() — is
unaffected.

Full Changelog: 3.4...3.5

3.4

3.4

Choose a tag to compare

@nadar nadar released this 16 Sep 15:29

What's Changed

  • docs(blocks): document the composer script route for the generator by @nadar in #5

Full Changelog: 3.3...3.4

3.3

3.3

Choose a tag to compare

@nadar nadar released this 07 Sep 21:04
915e970

Purely additive. Nothing in lib/Api or lib/Model changed, no runtime behaviour changed, and
no existing code needs touching.

New: vendor/bin/flyo-generate-blocks

The package now ships a binary that generates one typed PHP class per Nitro block from your
integration's OpenAPI document, so $block->getContent()->image->source is understood by your IDE
and PHPStan instead of being a bare \stdClass. See the "Typed Blocks" section of the README.

The generated classes extend \Flyo\Model\Block and are documentation-only: nothing instantiates
them, and a block returned by PagesApi is still a plain \Flyo\Model\Block at runtime. Adopt
them by changing an annotation at your framework boundary:

// before
/** @var \Flyo\Model\Block $block */

// after
/** @var \App\Blocks\BlockHero $block */

Typed block schemas come from the authenticated /nitro/v1/openapi/schemas endpoint; the public
/nitro/v1/openapi does not carry them.

What's Changed

  • flyo generate block cli by @nadar in #4

Full Changelog: 3.2...3.3

3.2

3.2

Choose a tag to compare

@nadar nadar released this 03 Sep 08:18

feat(model): add is_indexable field to Entity and Page

Add is_indexable property to expose whether an entity or page may
be indexed by search engines, distinct from access control and
visibility flags. Update generated getters/setters, attribute maps,
and validation for the new field. Regenerate API docs for Entity
and Page models. Bump OpenAPI document version to 2.38.

Full Changelog: 3.1...3.2

3.1

3.1

Choose a tag to compare

@nadar nadar released this 01 Sep 06:23
  • new canonical information for entity detail

Full Changelog: 3.0...3.1

3.0

3.0

Choose a tag to compare

@nadar nadar released this 28 Aug 18:31
6ab526e

From 2.3 to 3.0

Generated against OpenAPI spec 2.35 (was 2.30).

This is a major release: the sitemap endpoint returns a different model with fewer fields,
which is a breaking change for anyone reading presentation data off sitemap items. Everything
else in this release is additive.

sitemap() returns its own model (breaking)

SitemapApi::sitemap() now returns \Flyo\Model\SitemapinterfaceInner[] instead of
\Flyo\Model\EntityinterfaceInner[]. The sitemap response has been reduced to the fields
a sitemap actually needs, so the new model only carries entity_unique_id, updated_at
and href, plus the deprecated entity_type, entity_slug and routes.

These getters no longer exist on sitemap items:

Removed from sitemap items Still available on
getEntityTitle() SearchApi::search(), EntitiesApi
getEntityTeaser() SearchApi::search(), EntitiesApi
getEntityImage() SearchApi::search(), EntitiesApi
getEntityTimeStart() SearchApi::search(), EntitiesApi
getEntityTypeId() SearchApi::search(), EntitiesApi
// 2.3
/** @var \Flyo\Model\EntityinterfaceInner[] $items */
$items = (new \Flyo\Api\SitemapApi())->sitemap();
$items[0]->getEntityTitle();

// 3.0
/** @var \Flyo\Model\SitemapinterfaceInner[] $items */
$items = (new \Flyo\Api\SitemapApi())->sitemap();
$items[0]->getHref();
$items[0]->getUpdatedAt();       // use as <lastmod>
$items[0]->getEntityUniqueId();  // correlate with the entities endpoint

If you type-hinted the sitemap result against \Flyo\Model\EntityinterfaceInner, replace it
with \Flyo\Model\SitemapinterfaceInner. EntityinterfaceInner itself is unchanged and is
still what SearchApi::search() returns.

Two further behaviour notes from the spec: entries without a resolvable URL are now omitted
from the sitemap, and updated_at on a Nitro page only moves when the delivered content
actually changed (a rebuild producing identical output does not bump it).

Prefer getHref() over getEntityType(), getEntitySlug() and getRoutes() — those three
are marked deprecated and only remain for consumers that build URLs themselves.

Draft links on Entity (new)

\Flyo\Model\Entity gained is_draft (bool) and draft_expires_at (float|null). A draft
link is an expiring snapshot of an entity that is still offline in Flyo, addressed by a token
that takes the place of the entity's unique id or slug, so it is resolved through the existing
EntitiesApi::entityByUniqueid() and EntitiesApi::entityBySlug() calls.

$entity = (new \Flyo\Api\EntitiesApi())->entityByUniqueid($uniqueidOrDraftToken);

if ($entity->getIsDraft()) {
    // not the live page - render a hint, and optionally show when the link dies
    $expiresAt = $entity->getDraftExpiresAt(); // Unix timestamp
}

is_draft is false for every regular request. Two things to watch out for: a draft token
does not look like a normal slug or unique id, so a router that validates those parameters
against a pattern has to let it through; and typeId does not apply to a draft token, so omit
that parameter when resolving one.

Documentation-only changes

SearchApi::search() is unchanged in signature, but the spec now documents its matching
behaviour: partial-word and diacritic-insensitive matching (t shirt finds T-Shirt,
Zurich/Zuerich find Zürich), a typo-tolerant second pass for words of at least four
characters, and how score weighs title over teaser and phrase matches over scattered words.

What's Changed

  • 3.0: update sdk to latest openapi version (2.35) by @nadar in #3

Full Changelog: 2.3...3.0

2.3

2.3

Choose a tag to compare

@nadar nadar released this 18 Aug 09:11
18325f3

Generated against OpenAPI spec 2.30 (was 2.28).

routes is a plain array again

The Routes model class introduced in 2.2 has been removed. EntityInterface::getRoutes()
and EntityinterfaceInner::getRoutes() return array<string,mixed>|null again, so all
route keys are accessible and no longer swallowed by the model.

// 2.2
$entity->getRoutes()->getEmpty();

// 2.3
$routes = $entity->getRoutes();
$routes['_empty']; // bool: true when no route could be resolved
$routes['detail']; // string: "/foo-bar"

If you type-hinted against \Flyo\Model\Routes, replace it with array.

What's Changed

  • Remove Routes model class and revert to plain array by @nadar in #2

Full Changelog: 2.2...2.3