PHPackages                             lukeoliff/zpg-rtf-php - 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. lukeoliff/zpg-rtf-php

AbandonedArchivedLibrary

lukeoliff/zpg-rtf-php
=====================

Package for ZPG Real Time Feed integration

v0.1.3(6y ago)63.0k11[1 issues](https://github.com/lukeoliff/zpg-rtf-php/issues)MITPHPPHP ~7

Since Jul 19Pushed 6y agoCompare

[ Source](https://github.com/lukeoliff/zpg-rtf-php)[ Packagist](https://packagist.org/packages/lukeoliff/zpg-rtf-php)[ RSS](/packages/lukeoliff-zpg-rtf-php/feed)WikiDiscussions master Synced yesterday

READMEChangelog (3)Dependencies (4)Versions (7)Used By (0)

I no longer have access to this API to continue working on the SDK. I am happy to transfer the project to someone. In the meantime, the project will be archived. Please nudge me on twitter.com/lukeocodes to discuss.

ZPG Real-time Listings Service for PHP
======================================

[](#zpg-real-time-listings-service-for-php)

[![Software License](https://camo.githubusercontent.com/f251623e510f5909f16ae3f4e6e548dac11340b9fde1a99be26b015b39272c00/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c6174)](LICENSE.md)[![Build Status](https://camo.githubusercontent.com/5a235d45447ba3fd8c7ccf682ea1f2f2e40918a4b976e98298505f5ff2039f1e/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f6c756b656f6c6966662f7a70672d7274662d7068702f6d61737465722e7376673f7374796c653d666c6174)](https://travis-ci.org/lukeoliff/zpg-rtf-php)[![Coverage Status](https://camo.githubusercontent.com/a7a7bfddaeb057c760d18281ebf2a0d7e2014a5cbd1862e31be6e31ec04d6e20/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f6c756b656f6c6966662f7a70672d7274662d7068702e7376673f7374796c653d666c6174)](https://scrutinizer-ci.com/g/lukeoliff/zpg-rtf-php/?branch=master)[![Code Quality](https://camo.githubusercontent.com/c546e7b4e4f8b38248d2f98f4d3ae83b4bb72c8fdec8b38519a7043a4905925c/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f6c756b656f6c6966662f7a70672d7274662d7068702f6d61737465722e7376673f7374796c653d666c6174)](https://scrutinizer-ci.com/g/lukeoliff/zpg-rtf-php/?branch=master)

Todo (in order of priority)
---------------------------

[](#todo-in-order-of-priority)

- Check enum's for their values on `set` instead of relying on JSON validation.
- Introduce better built in exception types and error handling.
- Use a JSON serialization library to create the request payloads instead of `\JSONSerializable`.
- Look at a Rightmove RTDF equivalent. 😇

Install
-------

[](#install)

### Via Composer

[](#via-composer)

```
composer require lukeoliff/zpg-rtf-php
```

Certificate File
----------------

[](#certificate-file)

Before making calls to the ZPG API, you will need to follow [Zoopla's instructions](https://realtime-listings.webservices.zpg.co.uk/docs/latest/documentation.html#security) for generating a public-private key-pair with which to authenticate against Zoopla's servers.

Once you have provided Zoopla with the generated certificate signing request file, they will verify and provide you with a certificate by email. Combine the certificate with the private key you have generated:

```
cat zoopla_provided_certificate.crt private.pem > combined.pem
```

Change the `$pathToZpgCert` variable to the location of your `combined.pem` file and you will be ready to authenticate against the ZPG servers.

Update/Create a listing
-----------------------

[](#updatecreate-a-listing)

This method allows you to describe a listing. It is used for both creation and update purposes and, in either case, the listing should be described in its entirety.

```
        use ZpgRtf\Methods\ListingMethod;
        use ZpgRtf\Objects\BranchObject;
        use ZpgRtf\Objects\ContentObject;
        use ZpgRtf\Objects\CoordinatesObject;
        use ZpgRtf\Objects\DescriptionObject;
        use ZpgRtf\Objects\EpcRatingsObject;
        use ZpgRtf\Objects\GoogleStreetViewObject;
        use ZpgRtf\Objects\ListingObject;
        use ZpgRtf\Objects\LocationObject;
        use ZpgRtf\Objects\PricingObject;

        $listing = new ListingObject();
        $listing->setAccessibility(false)
            ->setBasement(false)
            ->setBathrooms(4)
            ->setBranchReference('branch-001')
            ->setBurglarAlarm(true)
            ->setCategory('residential')
            ->setCentralHeating('full')
            ->setChainFree(true)
            ->setConnectedUtilities(['electricity', 'fibre_optic', 'gas', 'satellite_cable_tv', 'water'])
            ->setConservatory(false)
            ->setConstructionYear(2015)
            ->setCouncilTaxBand('D')
            ->setDecorativeCondition('excellent')
            ->setDisplayAddress('Some Parade, Essex')
            ->setDoubleGlazing(true)
            ->setFeatureList(['Feature 1', 'Feature 2', 'Feature 3', 'Feature 4', 'Feature 5'])
            ->setFireplace(true)
            ->setFloorLevels(['ground', 1, 2])
            ->setFloors(3)
            ->setGroundRent(99.99)
            ->setLifeCycleStatus('available')
            ->setListingReference('listing-000001')
            ->setLivingRooms(1)
            ->setLoft(true)
            ->setOutsideSpace(['private_garden', 'terrace'])
            ->setParking(['single_garage', 'off_street_parking'])
            ->setPropertyType('town_house')
            ->setRateableValue(12000)
            ->setSummaryDescription('A well decorated house.')
            ->setTenure('freehold')
            ->setTotalBedrooms(3)
            ->setUtilityRoom(true);

        $contentsImages = [
            'http://via.placeholder.com/800x600',
            'http://via.placeholder.com/800x600/ffffff',
            'http://via.placeholder.com/800x600/000000',
        ];

        $contents = [];

        foreach ($contentsImages as $key => $image) {
            $content = new ContentObject();
            $content->setUrl($image)
                ->setCaption('image: ' . $key)
                ->setType('image');

            $contents[] = $content;
        }

        $listing->setContent($contents);

        $descriptionTexts = [
            'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ut fermentum justo. Sed id magna eu ante
mattis semper. Vivamus purus lectus, sollicitudin vitae velit feugiat, porttitor rhoncus elit.',
            'Integer rhoncus nulla quis nibh malesuada interdum. Nulla fermentum neque nec lacus ullamcorper fringilla.
Mauris posuere quam nec erat accumsan, at sodales diam bibendum. Fusce vitae tortor purus.',
        ];

        $descriptions = [];

        foreach ($descriptionTexts as $text) {
            $description = new DescriptionObject();
            $description->setText($text);

            $descriptions[] = $description;
        }

        $listing->setDetailedDescription($descriptions);

        $epcRatings = new EpcRatingsObject();
        $epcRatings->setEerCurrentRating(84)
            ->setEerPotentialRating(92);

        $listing->setEpcRatings($epcRatings);

        $coordinates = new CoordinatesObject();
        $coordinates->setLatitude(52.0453067)
            ->setLongitude(0.7534206);

        $googleStreetView = new GoogleStreetViewObject();
        $googleStreetView->setCoordinates($coordinates)
            ->setHeading(25.84)
            ->setPitch(76.92);

        $listing->setGoogleStreetView($googleStreetView);

        $location = new LocationObject();
        $location->setPropertyNameOrNumber(9)
            ->setStreetName('Some Road')
            ->setLocality('Somefield')
            ->setTownOrCity('Somebury')
            ->setCounty('Somefolk')
            ->setPostalCode('SO10 2YA')
            ->setCountryCode('GB')
            ->setCoordinates($coordinates);

        $listing->setLocation($location);

        $pricing = new PricingObject();
        $pricing->setCurrencyCode('GBP')
            ->setPrice(289995)
            ->setPriceQualifier('from')
            ->setTransactionType('sale');

        $listing->setPricing($pricing);

        $pathToZpgCert = '../local/cert/file.pem';

        $method = new ListingMethod($pathToZpgCert);
        $response = $method->sendUpdate($listing);
```

Delete a listing
----------------

[](#delete-a-listing)

This method allows you to remove a listing from a branch's inventory list.

```
        use ZpgRtf\Methods\ListingMethod;
        use ZpgRtf\Objects\ListingDeleteObject;

        $listingDelete = new ListingDeleteObject();
        $listingDelete->setListingReference('listing-000001')
            ->setDeletionReason('withdrawn');

        $pathToZpgCert = '../local/cert/file.pem';

        $method = new ListingMethod($pathToZpgCert);
        $response = $method->sendDelete($listingDelete);
```

List all listings
-----------------

[](#list-all-listings)

Because of the incremental nature of the service it is possible for the data that ZPG has to drift relative to yours (because of network problems or uncaught errors, for example). It is recommended that you periodically check the synchronisation of data between their system and yours. The listing/list method allows you retrieve a summary of the listing inventory for a branch and their state.

```
        use ZpgRtf\Methods\ListingMethod;
        use ZpgRtf\Objects\BranchObject;

        $branch = new BranchObject();
        $branch->setBranchReference('branch-001');

        $pathToZpgCert = '../local/cert/file.pem';

        $method = new ListingMethod($pathToZpgCert);
        $response = $method->getList($branch);
```

Update/Create a branch
----------------------

[](#updatecreate-a-branch)

This method allows you to describe a branch, to which listings are then associated. The address and other contact details allow ZPG to identify the equivalent branch on our system and map your branch\_reference to theirs.

```
        use ZpgRtf\Methods\BranchMethod;
        use ZpgRtf\Objects\BranchObject;
        use ZpgRtf\Objects\CoordinatesObject;
        use ZpgRtf\Objects\LocationObject;
        use ZpgRtf\Objects\PafAddressObject;

        $branch = new BranchObject();
        $branch->setWebsite('https://www.testagent.com/branch-name')
            ->setTelephone('02081111121')
            ->setBranchReference('branch-001')
            ->setBranchName('branch-name')
            ->setEmail('branch-name@testagent.com');

        $branchLocation = new LocationObject();
        $branchLocation->setPropertyNameOrNumber(9)
            ->setStreetName('Some Road')
            ->setLocality('Somefield')
            ->setTownOrCity('Somebury')
            ->setCounty('Somefolk')
            ->setPostalCode('SO10 2YA')
            ->setCountryCode('GB');

        $branchCoordinates = new CoordinatesObject();
        $branchCoordinates->setLatitude(52.0451852)
            ->setLongitude(0.7523342);

        $branchLocation->setCoordinates($branchCoordinates);

        $branchPaf = new PafAddressObject();
        $branchPaf->setAddressKey('02341509')
            ->setOrganisationKey('00001150')
            ->setPostcodeType('S');

        $branchLocation->setPafAddress($branchPaf)
            ->setPafUdprn('00001234');

        $branch->setLocation($branchLocation);

        $pathToZpgCert = '../local/cert/file.pem';

        $method = new BranchMethod($pathToZpgCert);
        $response = $method->sendUpdate($branch);
```

Credit
------

[](#credit)

It's worth mentioning that for no other reason than consistency that descriptions of methods and objects have been lifted straight from [ZPG's Real-time Listing Service documentation](https://realtime-listings.webservices.zpg.co.uk/docs/latest/documentation.html#methods).

Contributing
------------

[](#contributing)

Please see [code of conduct](CODE_OF_CONDUCT.md) and [contributing guide](CONTRIBUTING.md) if interested in contributing.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance17

Infrequent updates — may be unmaintained

Popularity25

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 97.7% 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 ~501 days

Total

3

Last Release

2216d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/40ad6e82fb9fb26b1f50b149c4c0b02651d0faf498aaced35c861720951b1f02?d=identicon)[lukeoliff](/maintainers/lukeoliff)

---

Top Contributors

[![lukeocodes](https://avatars.githubusercontent.com/u/956290?v=4)](https://github.com/lukeocodes "lukeocodes (172 commits)")[![richardjellis](https://avatars.githubusercontent.com/u/868258?v=4)](https://github.com/richardjellis "richardjellis (4 commits)")

---

Tags

zooplazoopla-api

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/lukeoliff-zpg-rtf-php/health.svg)

```
[![Health](https://phpackages.com/badges/lukeoliff-zpg-rtf-php/health.svg)](https://phpackages.com/packages/lukeoliff-zpg-rtf-php)
```

###  Alternatives

[neuron-core/neuron-ai

The PHP Agentic Framework.

1.8k245.3k21](/packages/neuron-core-neuron-ai)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3731.2M42](/packages/tencentcloud-tencentcloud-sdk-php)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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