ujamii / openimmo
OpenImmo library for PHP8. Read and write OpenImmo xml format with JMS Serializer.
Fund package maintenance!
mgrundkoetter
Installs: 27 974
Dependents: 3
Suggesters: 0
Security: 0
Stars: 44
Watchers: 5
Forks: 11
Open Issues: 3
Requires
- php: >=8.1
- ext-dom: *
- ext-simplexml: *
- doctrine/annotations: ^2.0
- jms/serializer: ^2.1 || ^3.5
Requires (Dev)
- ext-json: *
- friendsofphp/php-cs-fixer: ^3.0
- goetas-webservices/xsd-reader: ^0.4
- infection/infection: >=0.16
- nette/php-generator: ^4.0
- phpstan/phpstan: ^1.0
- phpunit/phpunit: >=7.5 <10
- rector/rector: >=0.18
- symfony/serializer: ^5.3 || ^6.0
This package is auto-updated.
Last update: 2024-11-02 07:34:12 UTC
README
OpenImmo and the OpenImmo logo are registered trademarks of the OpenImmo e.V. Neither is this package an official distribution nor am I associated with this organisation!
This library just wraps the OpenImmo XML format with some PHP8 classes. If you need support for PHP <= 8.1, see version 1.x of this package. Version 2 is for PHP >=8.2 only.
There is an official library available at http://www.openimmo.de/go.php/p/22/support20.htm which costs 95 EUR excl. VAT and is "compatible with PHP5 and tested with PHP 8.1" (end quote). To completely convince you, you will only be allowed to see the code after you have paid and they have a no-refund policy.
Important note
I don't want to include real world xml examples into this distribution package due possible license and privacy issues. Thus, some tests are automatically skipped, if the xml files are not found in the examples directory! The "Open" in OpenImmo has nothing to do with Open Source (I was told ;-)
TODOs
- add test cases, especially for the example file provided with the official download package.
Installation
composer req ujamii/openimmo
Integrations
If you like to use this API as base for an integration into a CMS or Framework, feel free to contact me, I will link it here.
- Integration into TYPO3 CMS, extension "openimmo"
- NEOS CMS, package "Ujamii.OpenImmoNeos"
Usage
Writing OpenImmo XML
// just create the elements you need in your xml and use the set-methods to fill in values. $nutzungsart = new Nutzungsart(); $nutzungsart ->setWohnen(true) ->setGewerbe(false) ->setAnlage(false) ->setWaz(false); $serializer = \JMS\Serializer\SerializerBuilder::create()->build(); echo $serializer->serialize($nutzungsart, 'xml');
will produce
<nutzungsart WOHNEN="true" GEWERBE="false" ANLAGE="false" WAZ="false" />
Nested elements are created just as easy. Classes, properties, constants and parameters are named as corresponding items in the xsd file. They are just converted to camelCase to comply with PHP standards.
$infrastrktur = new Infrastruktur(); $infrastrktur ->setZulieferung(false) ->setAusblick((new Ausblick())->setBlick(Ausblick::BLICK_BERGE)) ->setDistanzenSport([ new DistanzenSport(DistanzenSport::DISTANZ_ZU_SPORT_SEE, 15) ]) ->setDistanzen([ new Distanzen(Distanzen::DISTANZ_ZU_HAUPTSCHULE, 22) ]); $serializer = \JMS\Serializer\SerializerBuilder::create()->build(); echo $serializer->serialize($infrastrktur, 'xml');
will generate
<infrastruktur> <ausblick blick="BERGE" /> <distanzen distanz_zu="HAUPTSCHULE" >22.0</distanzen> <distanzen_sport distanz_zu_sport="SEE" >15.0</distanzen_sport> <zulieferung>false</zulieferung> </infrastruktur>
Reading OpenImmo XML
Reading data from xml into a easy-to-use object structure is also pretty straightforward. This example will generate a list of objects (addresses).
$xmlString = file_get_contents('./example/foobar.xml'); /* @var $openImmo \Ujamii\OpenImmo\API\Openimmo */ $openImmo = $serializer->deserialize($xmlString, \Ujamii\OpenImmo\API\Openimmo::class, 'xml'); /* @var $anbieter \Ujamii\OpenImmo\API\Anbieter */ foreach ($openImmo->getAnbieter() as $anbieter) { /* @var $immobilie \Ujamii\OpenImmo\API\Immobilie */ foreach ($anbieter->getImmobilie() as $immobilie) { echo PHP_EOL . vsprintf('%s %s, %s %s', [ $immobilie->getGeo()->getStrasse(), $immobilie->getGeo()->getHausnummer(), $immobilie->getGeo()->getPlz(), $immobilie->getGeo()->getOrt(), ]); } }
Writing JSON (since v0.10)
Although the OpenImmo standard just describes an XML version, there may be cases when you want to generate JSON from the given data. Sadly, there is an issue with custom types, scalar values and JSON serialization in the JMS serializer. However, it is still possible to write JSON format with the Symfony serializer component.
composer require symfony/serializer
Generating JSON then works like this:
use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer; use Symfony\Component\Serializer\Serializer; $openImmoObject = null; // this may be any object of one of the API classes from this package $encoders = [new JsonEncoder()]; $normalizers = [ new DateTimeNormalizer(), new GetSetMethodNormalizer() ]; $serializerContext = [ AbstractObjectNormalizer::SKIP_NULL_VALUES => true, AbstractObjectNormalizer::PRESERVE_EMPTY_OBJECTS => false, 'json_encode_options' => \JSON_PRESERVE_ZERO_FRACTION ]; $serializer = new Serializer($normalizers, $encoders); $jsonContent = $this->serializer->serialize($openImmoObject, JsonEncoder::FORMAT, $serializerContext);
Possible issues
DateTime format not working
Some tools may generate DateTime values in the xml, which cause errors like
Fatal error: Uncaught JMS\Serializer\Exception\RuntimeException: Invalid datetime "2020-08-07T11:56:39.1242974+02:00", expected one of the format "Y-m-d\TH:i:sP", "Y-m-d\TH:i:s".
This can be caused by a different precision for the microsecond part (1242974) of this value. As the default PHP precision may be lower that the one of the tool, which the xml was generated with. If this problem occurs with the data you use, you can add a handler, included in this package, to the serializer like this:
use JMS\Serializer\Handler\HandlerRegistryInterface; use Ujamii\OpenImmo\Handler\DateTimeHandler; $builder = \JMS\Serializer\SerializerBuilder::create(); $builder ->configureHandlers(function(HandlerRegistryInterface $registry) { $registry->registerSubscribingHandler(new DateTimeHandler()); }) ; $serializer = $builder->build();
Update API classes with a new OpenImmo version
- Install composer package.
- Download OpenImmo files from their website (extract into the example folder). Their license agreement denies redistribution of the xsd file.
php -f generate-api.php
will fill thesrc/API
directory with new classes.composer dumpautoload
to update the autoloading.- Done.
Running tests
composer run phpunit
License and Contribution
As this is OpenSource, you are very welcome to contribute by reporting bugs, improve the code, write tests or whatever you are able to do to improve the project.
If you want to do me a favour, buy me something from my Amazon wishlist.
Thank you!
- Qbus Internetagentur GmbH for your code contribution