PHPackages                             zfcampus/zf-hal - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. zfcampus/zf-hal

Abandoned → [laminas-api-tools/api-tools-hal](/?search=laminas-api-tools%2Fapi-tools-hal)ArchivedLibrary[HTTP &amp; Networking](/categories/http)

zfcampus/zf-hal
===============

ZF2 Module providing Hypermedia Application Language assets and rendering

1.6.0(7y ago)312.1M↓40.1%49[22 issues](https://github.com/zfcampus/zf-hal/issues)[1 PRs](https://github.com/zfcampus/zf-hal/pulls)12BSD-3-ClausePHPPHP ^5.6 || ^7.0

Since Sep 12Pushed 6y ago2 watchersCompare

[ Source](https://github.com/zfcampus/zf-hal)[ Packagist](https://packagist.org/packages/zfcampus/zf-hal)[ Docs](http://apigility.org/)[ RSS](/packages/zfcampus-zf-hal/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (6)Dependencies (13)Versions (27)Used By (12)

ZF HAL
======

[](#zf-hal)

> ## Repository abandoned 2019-12-31
>
> [](#repository-abandoned-2019-12-31)
>
> This repository has moved to [laminas-api-tools/api-tools-hal](https://github.com/laminas-api-tools/api-tools-hal).

[![Build Status](https://camo.githubusercontent.com/8db8ab2193a80785782b2b6f563718bcef86f07c89c3d08b66a1d1e9b8fa4c08/68747470733a2f2f7472617669732d63692e6f72672f7a6663616d7075732f7a662d68616c2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/zfcampus/zf-hal)[![Coverage Status](https://camo.githubusercontent.com/19f27ae43752aa04f3b5dff75e7b13497c91232e8463e86472bb666affd15faa/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f7a6663616d7075732f7a662d68616c2f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/zfcampus/zf-hal?branch=master)

Introduction
------------

[](#introduction)

This module provides the ability to generate [Hypermedia Application Language](http://tools.ietf.org/html/draft-kelly-json-hal-06) JSON representations.

Requirements
------------

[](#requirements)

Please see the [composer.json](composer.json) file.

Installation
------------

[](#installation)

Run the following `composer` command:

```
$ composer require zfcampus/zf-hal
```

Alternately, manually add the following to your `composer.json`, in the `require` section:

```
"require": {
    "zfcampus/zf-hal": "^1.4"
}
```

And then run `composer update` to ensure the module is installed.

Finally, add the module name to your project's `config/application.config.php` under the `modules`key:

```
return [
    /* ... */
    'modules' => [
        /* ... */
        'ZF\Hal',
    ],
    /* ... */
];
```

> ### zf-component-installer
>
> [](#zf-component-installer)
>
> If you use [zf-component-installer](https://github.com/zendframework/zf-component-installer), that plugin will install zf-hal as a module for you.

Configuration
=============

[](#configuration)

### User Configuration

[](#user-configuration)

This module utilizes the top level key `zf-hal` for user configuration.

#### Key: `renderer`

[](#key-renderer)

This is a configuration array used to configure the `zf-hal` `Hal` view helper/controller plugin. It consists of the following keys:

- `default_hydrator` - when present, this named hydrator service will be used as the default hydrator by the `Hal` plugin when no hydrator is configured for an entity class.
- `render_embedded_entities` - boolean, default `true`, to render full embedded entities in HAL responses; if `false`, embedded entities will contain only their relational links.
- `render_embedded_collections` - boolean, default is `true`, to render collections in HAL responses; if `false`, only a collection's relational links will be rendered.
- `hydrators` - a map of entity class names to hydrator service names that the `Hal` plugin can use when hydrating entities.

#### Key: `metadata_map`

[](#key-metadata_map)

The metadata map is used to hint to the `Hal` plugin how it should render objects of specific class types. When the `Hal` plugin encounters an object found in the metadata map, it will use the configuration for that class when creating a representation; this information typically indicates how to generate relational links, how to serialize the object, and whether or not it represents a collection.

Each class in the metadata map may contain one or more of the following configuration keys:

- `entity_identifier_name` - name of the class property (after serialization) used for the identifier.
- `route_name` - a reference to the route name used to generate `self` relational links for the collection or entity.
- `route_identifier_name` - the identifier name used in the route that will represent the entity identifier in the URI path. This is often different than the `entity_identifier_name` as each variable segment in a route must have a unique name.
- `hydrator` - the hydrator service name to use when serializing an entity.
- `is_collection` - boolean; set to `true` when the class represents a collection.
- `links` - an array of configuration for constructing relational links; see below for the structure of links.
- `entity_route_name` - route name for embedded entities of a collection.
- `route_params` - an array of route parameters to use for link generation.
- `route_options` - an array of options to pass to the router during link generation.
- `url` - specific URL to use with this resource, if not using a route.
- `max_depth` - integer; limit to what nesting level entities and collections are rendered; if the limit is reached, only `self` links will be rendered. default value is `null`, which means no limit: if unlimited circular references are detected, an exception will be thrown to avoid infinite loops.
- `force_self_link` - boolean; set whether a self-referencing link should be automatically generated for the entity. Defaults to `true` (since its recommended).

The `links` property is an array of arrays, each with the following structure:

```
[
    'rel'   => 'link relation',
    'url'   => 'string absolute URI to use', // OR
    'route' => [
        'name'    => 'route name for this link',
        'params'  => [ /* any route params to use for link generation */ .,
        'options' => [ /* any options to pass to the router */ .,
    .,
.,
// repeat as needed for any additional relational links
```

#### Key: `options`

[](#key-options)

The options key is used to configure general options of the Hal plugin. For now we have only one option available who contains the following configuration key:

- `use_proxy` - boolean; set to `true` when you are using a proxy (for using `HTTP_X_FORWARDED_PROTO`, `HTTP_X_FORWARDED_HOST`, and `HTTP_X_FORWARDED_PORT` instead of `SSL_HTTPS`, `HTTP_HOST, SERVER_PORT`)

### System Configuration

[](#system-configuration)

The following configuration is present to ensure the proper functioning of this module in a ZF2-based application.

```
// Creates a "HalJson" selector for use with zfcampus/zf-content-negotiation
'zf-content-negotiation' => [
    'selectors' => [
        'HalJson' => [
            'ZF\Hal\View\HalJsonModel' => [
                'application/json',
                'application/*+json',
            ],
        ],
    ],
],
```

ZF2 Events
==========

[](#zf2-events)

### Events

[](#events)

#### ZF\\Hal\\Plugin\\Hal Event Manager

[](#zfhalpluginhal-event-manager)

The `ZF\Hal\Plugin\Hal` triggers several events during its lifecycle. From the `EventManager`instance composed into the HAL plugin, you may attach to the following events:

- `renderCollection`
- `renderCollection.post`
- `renderEntity`
- `renderEntity.post`
- `createLink`
- `renderCollection.entity`
- `getIdFromEntity`

As an example, you could listen to the `renderEntity` event as follows (the following is done within a `Module` class for a ZF2 module and/or Apigility API module):

```
class Module
{
    public function onBootstrap($e)
    {
        $app = $e->getTarget();
        $services = $app->getServiceManager();
        $helpers  = $services->get('ViewHelperManager');
        $hal      = $helpers->get('Hal');

        // The HAL plugin's EventManager instance does not compose a SharedEventManager,
        // so you must attach directly to it.
        $hal->getEventManager()->attach('renderEntity', [$this, 'onRenderEntity']);
    }

    public function onRenderEntity($e)
    {
        $entity = $e->getParam('entity');
        if (! $entity->getEntity() instanceof SomeTypeIHaveDefined) {
            // do nothing
            return;
        }

        // Add a "describedBy" relational link
        $entity->getLinks()->add(\ZF\Hal\Link\Link::factory([
            'rel' => 'describedBy',
            'route' => [
                'name' => 'my/api/docs',
            ],
        ]));
    }
}
```

Notes on individual events:

- `renderCollection` defines one parameter, `collection`, which is the `ZF\Hal\Collection` being rendered.
- `renderCollection.post` defines two parameters: `collection`, which is the `ZF\Hal\Collection` being rendered, and `payload`, an `ArrayObject`representation of the collection, including the page count, size, and total items, and links.
- `renderEntity` defines one parameter, `entity`, which is the `ZF\Hal\Entity` being rendered.
- `renderEntity.post` defines two parameters: `entity`, which is the `ZF\Hal\Entity` being rendered, and `payload`, an `ArrayObject`representation of the entity, including links.
- `createLink` defines the following event parameters:
    - `route`, the route name to use when generating the link, if any.
    - `id`, the entity identifier value to use when generating the link, if any.
    - `entity`, the entity for which the link is being generated, if any.
    - `params`, any additional routing parameters to use when generating the link.
- `renderCollection.entity` defines the following event parameters:
    - `collection`, the `ZF\Hal\Collection` to which the entity belongs.
    - `entity`, the current entity being rendered; this may or may not be a `ZF\Hal\Entity`.
    - `route`, the route name for the current entity.
    - `routeParams`, route parameters to use when generating links for the current entity.
    - `routeOptions`, route options to use when generating links for the current entity.
- `getIdFromEntity` defines one parameter, `entity`, which is an array or object from which an identifier needs to be extracted.
- `fromLink.pre` (since 1.5.0) defines one parameter, `linkDefinition`, which is a `ZF\Hal\Link\Link` instance. This is generally useful from `ZF\Rest\RestController::create()`, when you may want to manipulate the self relational link for purposes of generating the `Link` header.

### Listeners

[](#listeners)

#### ZF\\Hal\\Module::onRender

[](#zfhalmoduleonrender)

This listener is attached to `MvcEvent::EVENT_RENDER` at priority `100`. If the controller service result is a `HalJsonModel`, this listener attaches the `ZF\Hal\JsonStrategy` to the view at priority `200`.

ZF2 Services
============

[](#zf2-services)

### Models

[](#models)

#### ZF\\Hal\\Collection

[](#zfhalcollection)

`Collection` is responsible for modeling general collections as HAL collections, and composing relational links.

#### ZF\\Hal\\Entity

[](#zfhalentity)

`Entity` is responsible for modeling general purpose entities and plain objects as HAL entities, and composing relational links.

#### ZF\\Hal\\Link\\Link

[](#zfhallinklink)

`Link` is responsible for modeling a relational link. The `Link` class also has a static `factory()` method that can take an array of information as an argument to produce valid `Link`instances.

#### ZF\\Hal\\Link\\LinkCollection

[](#zfhallinklinkcollection)

`LinkCollection` is a model responsible for aggregating a collection of `Link` instances.

#### ZF\\Hal\\Metadata\\Metadata

[](#zfhalmetadatametadata)

`Metadata` is responsible for collecting all the necessary dependencies, hydrators and other information necessary to create HAL entities, links, or collections.

#### ZF\\Hal\\Metadata\\MetadataMap

[](#zfhalmetadatametadatamap)

The `MetadataMap` aggregates an array of class name keyed `Metadata` instances to be used in producing HAL entities, links, or collections.

### Extractors

[](#extractors)

#### ZF\\Hal\\Extractor\\LinkExtractor

[](#zfhalextractorlinkextractor)

`LinkExtractor` is responsible for extracting a link representation from `Link` instance.

#### ZF\\Hal\\Extractor\\LinkCollectionExtractor

[](#zfhalextractorlinkcollectionextractor)

`LinkCollectionExtractor` is responsible for extracting a collection of `Link` instances. It also composes a `LinkExtractor` for extracting individual links.

### Controller Plugins

[](#controller-plugins)

#### ZF\\Hal\\Plugin\\Hal (a.k.a. "Hal")

[](#zfhalpluginhal-aka-hal)

This class operates both as a view helper and as a controller plugin. It is responsible for providing controllers the facilities to generate HAL data models, as well as rendering relational links and HAL data structures.

### View Layer

[](#view-layer)

#### ZF\\Hal\\View\\HalJsonModel

[](#zfhalviewhaljsonmodel)

`HalJsonModel` is a view model that when used as the result of a controller service response signifies to the `zf-hal` module that the data within the model should be utilized to produce a JSON HAL representation.

#### ZF\\Hal\\View\\HalJsonRenderer

[](#zfhalviewhaljsonrenderer)

`HalJsonRenderer` is a view renderer responsible for rendering `HalJsonModel` instances. In turn, this renderer will call upon the `Hal` plugin/view helper in order to transform the model content (an `Entity` or `Collection`) into a HAL representation.

#### ZF\\Hal\\View\\HalJsonStrategy

[](#zfhalviewhaljsonstrategy)

`HalJsonStrategy` is responsible for selecting `HalJsonRenderer` when it identifies a `HalJsonModel`as the controller service response.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance6

Infrequent updates — may be unmaintained

Popularity53

Moderate usage in the ecosystem

Community36

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 84.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~82 days

Recently: every ~222 days

Total

24

Last Release

2761d ago

Major Versions

0.9.1 → 1.0.0beta22014-04-15

PHP version history (5 changes)0.6.0PHP &gt;=5.3.3

0.8.0PHP &gt;=5.4.8

0.9.0PHP &gt;=5.3.23

1.2.0PHP &gt;=5.5

1.4.0PHP ^5.6 || ^7.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/296074?v=4)[Zend Framework](/maintainers/zendframework)[@zendframework](https://github.com/zendframework)

---

Top Contributors

[![weierophinney](https://avatars.githubusercontent.com/u/25943?v=4)](https://github.com/weierophinney "weierophinney (904 commits)")[![neeckeloo](https://avatars.githubusercontent.com/u/1768645?v=4)](https://github.com/neeckeloo "neeckeloo (33 commits)")[![Wilt](https://avatars.githubusercontent.com/u/2419627?v=4)](https://github.com/Wilt "Wilt (20 commits)")[![michalbundyra](https://avatars.githubusercontent.com/u/7423207?v=4)](https://github.com/michalbundyra "michalbundyra (18 commits)")[![TomHAnderson](https://avatars.githubusercontent.com/u/493920?v=4)](https://github.com/TomHAnderson "TomHAnderson (15 commits)")[![acabala](https://avatars.githubusercontent.com/u/530622?v=4)](https://github.com/acabala "acabala (11 commits)")[![gsomoza](https://avatars.githubusercontent.com/u/106219?v=4)](https://github.com/gsomoza "gsomoza (8 commits)")[![localheinz](https://avatars.githubusercontent.com/u/605483?v=4)](https://github.com/localheinz "localheinz (8 commits)")[![ralphschindler](https://avatars.githubusercontent.com/u/76674?v=4)](https://github.com/ralphschindler "ralphschindler (6 commits)")[![ezimuel](https://avatars.githubusercontent.com/u/475967?v=4)](https://github.com/ezimuel "ezimuel (6 commits)")[![telkins](https://avatars.githubusercontent.com/u/53731?v=4)](https://github.com/telkins "telkins (6 commits)")[![tjlytle](https://avatars.githubusercontent.com/u/125074?v=4)](https://github.com/tjlytle "tjlytle (6 commits)")[![MichaelGooden](https://avatars.githubusercontent.com/u/1275012?v=4)](https://github.com/MichaelGooden "MichaelGooden (5 commits)")[![bartbrinkman](https://avatars.githubusercontent.com/u/8309358?v=4)](https://github.com/bartbrinkman "bartbrinkman (5 commits)")[![oxodesign](https://avatars.githubusercontent.com/u/175456?v=4)](https://github.com/oxodesign "oxodesign (3 commits)")[![thomasvargiu](https://avatars.githubusercontent.com/u/732012?v=4)](https://github.com/thomasvargiu "thomasvargiu (3 commits)")[![vixriihi](https://avatars.githubusercontent.com/u/5203261?v=4)](https://github.com/vixriihi "vixriihi (3 commits)")[![Maks3w](https://avatars.githubusercontent.com/u/1301698?v=4)](https://github.com/Maks3w "Maks3w (2 commits)")[![remybreuils](https://avatars.githubusercontent.com/u/1191532?v=4)](https://github.com/remybreuils "remybreuils (2 commits)")[![EvanDotPro](https://avatars.githubusercontent.com/u/5607?v=4)](https://github.com/EvanDotPro "EvanDotPro (1 commits)")

---

Tags

restpsr-13zendhalmodulezf2

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/zfcampus-zf-hal/health.svg)

```
[![Health](https://phpackages.com/badges/zfcampus-zf-hal/health.svg)](https://phpackages.com/packages/zfcampus-zf-hal)
```

###  Alternatives

[zfr/zfr-rest

Zend Framework 2 REST Module.

8120.7k](/packages/zfr-zfr-rest)[zfr/zfr-cors

Zend Framework module that let you deal with CORS requests

611.3M3](/packages/zfr-zfr-cors)[mezzio/mezzio-hal

Hypertext Application Language implementation for PHP and PSR-7

21500.9k6](/packages/mezzio-mezzio-hal)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
