Unverified Commit 8940dbd1 authored by Sam Williams's avatar Sam Williams Committed by GitHub
Browse files

Merge pull request #58 from Badcow/Version3

Version 3
parents cf3275a1 7911f49f
......@@ -2,4 +2,4 @@ vendor
phpunit.xml
composer.lock
coverage.clover
.php_cs.cache
\ No newline at end of file
*.cache
......@@ -23,6 +23,9 @@ $config = PhpCsFixer\Config::create()
'header_comment' => ['header' => $header],
'array_syntax' => ['syntax' => 'short'],
'ordered_imports' => ['sort_algorithm' => 'alpha'],
'void_return' => true,
'declare_strict_types' => true,
'no_superfluous_phpdoc_tags' => false,
])
->setFinder($finder)
;
......
filter:
excluded_paths: [tests/*]
checks:
php:
code_rating: true
remove_extra_empty_lines: true
remove_php_closing_tag: true
remove_trailing_whitespace: true
fix_use_statements:
remove_unused: true
preserve_multiple: false
preserve_blanklines: true
order_alphabetically: true
fix_php_opening_tag: true
fix_linefeed: true
fix_line_ending: true
fix_identation_4spaces: true
fix_doc_comments: true
tools:
external_code_coverage: true
php_analyzer: true
php_code_coverage: false
php_code_sniffer:
config:
standard: PSR2
filter:
paths: ['lib']
php_loc:
enabled: true
excluded_dirs: [vendor]
php_cpd:
enabled: true
excluded_dirs: [vendor]
paths:
- lib/
excluded_paths:
- tests/
dependency_paths:
- vendor/
build:
nodes:
analysis:
tests:
override:
- php-scrutinizer-run
coverage:
tests:
override:
- command: vendor/bin/phpunit --coverage-clover=coverage.clover
coverage:
file: coverage.clover
format: clover
\ No newline at end of file
language: php
php:
- 7.1
- 7.2
- 7.3
- 7.4snapshot
install: composer install
......@@ -11,10 +11,6 @@ script:
- vendor/bin/phpstan analyse --no-interaction --no-progress
- vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
notifications:
email:
- sam@badcow.co
\ No newline at end of file
CHANGELOG for 3.x
=================
## 3.0
* Use `rlanvin/php-ip` version 2 [Issue #43](https://github.com/Badcow/DNS/issues/43).
* Namespace `Badcow\DNS\Rdata\DNSSEC` is deprecated and deleted. [Issue #42](https://github.com/Badcow/DNS/issues/42).
* Deleted deprecated constants:
* `\Badcow\DNS\Parser\Normaliser::COMMENTS_NONE`
* `\Badcow\DNS\Parser\Normaliser::COMMENTS_END_OF_RECORD_ENTRY`
* `\Badcow\DNS\Parser\Normaliser::COMMENTS_WITHIN_MULTILINE`
* `\Badcow\DNS\Parser\Normaliser::COMMENTS_WITHOUT_RECORD_ENTRY`
* `\Badcow\DNS\Parser\Normaliser::COMMENTS_ALL`
* Upgraded to PHPUnit 8.
* Deprecated and deleted method `RdataInterface::output()` in favour of `RdataInterface::toText()`.
* New `RdataInterface` methods:
* `RdataInterface::toText()` same as `RdataInterface::output()`
* `RdataInterface::fromText()` construct an Rdata object from an Rdata string.
* `RdataInterface::toWire()` Return rdata in its wire format ready to be placed in DNS request/response packet.
* `RdataInterface::fromWire()` construct an Rdata object from wire formatted Rdata.
* `RdataInterface::getTypeCode()` return the IANA Resource Record type code.
* Enforce strict_types [Issue #37](https://github.com/Badcow/DNS/issues/37).
* Support more additional RDATA types [Issue #55](https://github.com/Badcow/DNS/issues/55):
* AFSDB
* CDNSKEY
* CDS
* CERT
* CSYNC
* DHCID
* DLV
* HIP
* IPSECKEY
* KEY
* KX
* NAPTR
* NSEC3
* NSEC3PARAM
* RP
* SIG
* SSHFP
* TA
* TKEY
* TLSA
* TSIG
* URI
* New Validator methods:
* `Validator::isBase64Encoded()`
* `Validator::isUnsignedInteger()`
* `Validator::isBase16Encoded()`
* `Validator::isBase32Encoded()`
* `Validator::isBase32HexEncoded()`
* Deprecate and delete NSEC methods:
* `NSEC::addTypeBitMap()` replaced with `NSEC::addType()`
* `NSEC::clearTypeMap()` replaced with `NSEC::clearTypes()`
* `NSEC::getTypeBitMaps()` replaced with `NSEC::getTypes()`
* Deleted ResourceRecord::__construct(); the same functionality has been moved to static method ResourceRecord::create();
* Rename class `Bacow\DNS\Rdata\TypeCodes` to `Badcow\DNS\Rdata\Types`.
* Delete class `Badcow\DNS\Parser\RDataTypes` as the same functionality exists in `Badcow\DNS\Rdata\Types`.
* Added the Unknown Record Type `Badcow\DNS\Rdata\UnknownType` which complies with [RFC 3597 - Handling of Unknown DNS Resource
Record (RR) Types](https://tools.ietf.org/html/rfc3597).
* Deleted class `Badcow\DNS\IP\Toolbox`, moved all methods to `Badcow\DNS\IP\PTR`.
\ No newline at end of file
Badcow DNS Zone Library
=======================
Badcow DNS Library
==================
The aim of this project is to create abstract object representations of DNS records in PHP. The project consists of various
classes representing DNS objects (such as `Zone`, `ResourceRecord`, and various `RData` types), a parser to convert BIND
style text files to the PHP objects, and builders to create aesthetically pleasing BIND records.
## Build Status
[![Build Status](https://travis-ci.org/Badcow/DNS.png)](https://travis-ci.org/Badcow/DNS) [![Code Coverage](https://scrutinizer-ci.com/g/Badcow/DNS/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Badcow/DNS/?branch=master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Badcow/DNS/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/Badcow/DNS/?branch=master)
[![Build Status](https://travis-ci.org/Badcow/DNS.png)](https://travis-ci.org/Badcow/DNS)
[![Code Coverage](https://scrutinizer-ci.com/g/Badcow/DNS/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Badcow/DNS/?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Badcow/DNS/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/Badcow/DNS/?branch=master)
## Contents
1. [Example usage](#example-usage)
......@@ -72,20 +74,7 @@ $mx3 = new ResourceRecord;
$mx3->setName('@');
$mx3->setRdata(Factory::Mx(30, 'mail-gw3.example.net.'));
$loc = new ResourceRecord;
$loc->setName('canberra');
$loc->setRdata(Factory::Loc(
-35.3075, //Lat
149.1244, //Lon
500, //Alt
20.12, //Size
200.3, //HP
300.1 //VP
));
$loc->setComment('This is Canberra');
$zone->addResourceRecord($soa);
$zone->addResourceRecord($loc);
$zone->addResourceRecord($mx2);
$zone->addResourceRecord($ns1);
$zone->addResourceRecord($mx3);
......@@ -125,16 +114,6 @@ ipv6.domain AAAA ::1; This is an IPv6 domain.
@ MX 10 mail-gw1.example.net.
@ MX 20 mail-gw2.example.net.
@ MX 30 mail-gw3.example.net.
; LOC RECORDS
canberra LOC (
35 18 27.000 S ; LATITUDE
149 7 27.840 E ; LONGITUDE
500.00m ; ALTITUDE
20.12m ; SIZE
200.30m ; HORIZONTAL PRECISION
300.10m ; VERTICAL PRECISION
); This is Canberra
```
The above is an example of the `AlignedBuilder` which creates records that are much more aesthetically pleasing. You can
......@@ -148,7 +127,6 @@ echo ZoneBuilder::build($zone);
$ORIGIN example.com.
$TTL 3600
@ IN SOA example.com. post.example.com. 2014110501 3600 14400 604800 3600
canberra LOC 35 18 27.000 S 149 7 27.840 E 500.00m 20.12m 200.30m 300.10m; This is Canberra
@ MX 20 mail-gw2.example.net.
@ IN NS ns1.nameserver.com.
@ MX 30 mail-gw3.example.net.
......@@ -159,24 +137,7 @@ ipv6.domain AAAA ::1; This is an IPv6 domain.
```
## Supported Types
* `A`
* `AAAA`
* `APL`
* `CNAME`
* `CAA`
* `DNAME`
* `HINFO`
* `LOC`
* `MX`
* `NS`
* `PTR`
* `SOA`
* `SRV`
* `TXT`
* `DNSKEY`
* `DS`
* `NSEC`
* `RRSIG`
All ubiquitous DNS types are supported. For full details on supported types see [the Documentation](docs/Supported-Types.md).
## Parsing BIND Records
......
......@@ -9,11 +9,12 @@
}
],
"require": {
"php": "~7.1",
"rlanvin/php-ip": "~1.0"
"php": "~7.2",
"rlanvin/php-ip": "~2.0",
"ademarre/binary-to-text-php": "@dev"
},
"require-dev": {
"phpunit/phpunit": "~7.5",
"phpunit/phpunit": "~8.4",
"friendsofphp/php-cs-fixer": "~2.1",
"phpstan/phpstan": "^0.11.6"
},
......
......@@ -60,6 +60,6 @@ foreach ($zone->getResourceRecords() as $record) {
$record->getName();
$record->getClass();
$record->getTtl();
$record->getRdata()->output();
$record->getRdata()->toText();
}
```
\ No newline at end of file
......@@ -6,9 +6,9 @@ The DNS Library can natively handle reverse IP records for both IPv4 and IPv6.
```php
use Badcow\DNS\Rdata\Factory;
use Badcow\DNS\{Zone, ResourceRecord, AlignedBuilder, Classes, ZoneBuilder};
use Badcow\DNS\Ip\Toolbox;
use Badcow\DNS\Ip\PTR;
$parent = Toolbox::reverseIpv4('158.133.7'); //Returns 7.133.158.in-addr.arpa.
$parent = PTR::reverseIpv4('158.133.7'); //Returns 7.133.158.in-addr.arpa.
$zone = new Zone($parent, 10800);
......@@ -43,20 +43,20 @@ $TTL 10800
```php
use Badcow\DNS\Rdata\Factory;
use Badcow\DNS\{Zone, ResourceRecord, AlignedBuilder, Classes, ZoneBuilder};
use Badcow\DNS\Ip\Toolbox;
use Badcow\DNS\Ip\PTR;
//$parent = Toolbox::reverseIpv4('158.133.7'); //Returns 7.133.158.in-addr.arpa.
$parent = Toolbox::reverseIpv6('2001:acad:5889:0:0:0:0');
//$parent = PTR::reverseIpv4('158.133.7'); //Returns 7.133.158.in-addr.arpa.
$parent = PTR::reverseIpv6('2001:acad:5889:0:0:0:0');
$zone = new Zone($parent, 10800);
$resourceRecords = [
new ResourceRecord(Toolbox::reverseIpv6('1', false), Factory::Ptr('gw-01.badcow.co.')),
new ResourceRecord(Toolbox::reverseIpv6('2', false), Factory::Ptr('gw-02.badcow.co.')),
new ResourceRecord(Toolbox::reverseIpv6('bad', false), Factory::Ptr('badcow.co.')),
new ResourceRecord(Toolbox::reverseIpv6('ff', false), Factory::Ptr('mail.badcow.co.'), 3600, Classes::INTERNET),
new ResourceRecord(Toolbox::reverseIpv6('aa1', false), Factory::Ptr('esw-01.badcow.co.')),
new ResourceRecord(Toolbox::reverseIpv6('aa2', false), Factory::Ptr('esw-02.badcow.co.')),
new ResourceRecord(PTR::reverseIpv6('1', false), Factory::Ptr('gw-01.badcow.co.')),
new ResourceRecord(PTR::reverseIpv6('2', false), Factory::Ptr('gw-02.badcow.co.')),
new ResourceRecord(PTR::reverseIpv6('bad', false), Factory::Ptr('badcow.co.')),
new ResourceRecord(PTR::reverseIpv6('ff', false), Factory::Ptr('mail.badcow.co.'), 3600, Classes::INTERNET),
new ResourceRecord(PTR::reverseIpv6('aa1', false), Factory::Ptr('esw-01.badcow.co.')),
new ResourceRecord(PTR::reverseIpv6('aa2', false), Factory::Ptr('esw-02.badcow.co.')),
];
$zone->fromArray($resourceRecords);
......
Supported Types
===============
Below are a list of the RData types supported by this library, while not every single type has been implemented, all
current in-use types have been. Other types can be implemented using the `Badcow\DNS\Rdata\PolymorphicRdata` object or
the Unknown Record Type `Badcow\DNS\Rdata\UnknownType` which complies with [RFC 3597 - Handling of Unknown DNS Resource
Record (RR) Types](https://tools.ietf.org/html/rfc3597).
| Type | Type ID | Defining RFC | Supported? | Usage* |
|------------|---------|-----------------------|------------|----------|
| A | 1 | RFC 1035 | ✔ | In Use |
| AAAA | 28 | RFC 3596 | ✔ | In Use |
| AFSDB | 18 | RFC 1183 | ✔ | In Use |
| APL | 42 | RFC 3123 | ✔ | In Use |
| CAA | 257 | RFC 6844 | ✔ | In Use |
| CDNSKEY | 60 | RFC 7344 | ✔ | In Use |
| CDS | 59 | RFC 7344 | ✔ | In Use |
| CERT | 37 | RFC 4398 | ✔ | In Use |
| CNAME | 5 | RFC 1035 | ✔ | In Use |
| CSYNC | 62 | RFC 7477 | ✔ | In Use |
| DHCID | 49 | RFC 4701 | ✔ | In Use |
| DLV | 32769 | RFC 4431 | ✔ | In Use |
| DNAME | 39 | RFC 6672 | ✔ | In Use |
| DNSKEY | 48 | RFC 4034 | ✔ | In Use |
| DS | 43 | RFC 4034 | ✔ | In Use |
| HIP | 55 | RFC 8005 | ✔ | In Use |
| IPSECKEY | 45 | RFC 4025 | ✔ | In Use |
| KEY | 25 | RFC 2535 & RFC 2930 | ✔ | In Use |
| KX | 36 | RFC 2230 | ✔ | In Use |
| LOC | 29 | RFC 1876 | ✔ | In Use |
| MX | 15 | RFC 1035 & RFC 7505 | ✔ | In Use |
| NAPTR | 35 | RFC 3403 | ✔ | In Use |
| NS | 2 | RFC 1035 | ✔ | In Use |
| NSEC | 47 | RFC 4034 | ✔ | In Use |
| NSEC3 | 50 | RFC 5155 | ✔ | In Use |
| NSEC3PARAM | 51 | RFC 5155 | ✔ | In Use |
| OPENPGPKEY | 61 | RFC 7929 | ✖ | In Use |
| PTR | 12 | RFC 1035 | ✔ | In Use |
| RP | 17 | RFC 1183 | ✔ | In Use |
| RRSIG | 46 | RFC 4034 | ✔ | In Use |
| SIG | 24 | RFC 2535 | ✔ | In Use |
| SMIMEA | 53 | RFC 8162 | ✖ | In Use |
| SOA | 6 | RFC 1035 & RFC 2308 | ✔ | In Use |
| SRV | 33 | RFC 2782 | ✔ | In Use |
| SSHFP | 44 | RFC 4255 | ✔ | In Use |
| TA | 32768 | N/A | ✔ | In Use |
| TKEY | 249 | RFC 2930 | ✔ | In Use |
| TLSA | 52 | RFC 6698 | ✔ | In Use |
| TSIG | 250 | RFC 2845 | ✔ | In Use |
| TXT | 16 | RFC 1035 | ✔ | In Use |
| URI | 256 | RFC 7553 | ✔ | In Use |
| A6 | 38 | RFC 2874 | ✖ | Obsolete |
| APL | 42 | RFC 3123 | ✔ | Obsolete |
| ATMA | 34 | N/A | ✖ | Obsolete |
| DOA | 259 | N/A | ✖ | Obsolete |
| EID | 31 | N/A | ✖ | Obsolete |
| EUI48 | 108 | RFC 7043 | ✖ | Obsolete |
| EUI64 | 109 | | ✖ | Obsolete |
| GID | 102 | N/A | ✖ | Obsolete |
| GPOS | 27 | RFC 1712 | ✖ | Obsolete |
| HINFO | 13 | RFC 883 | ✔ | Obsolete |
| ISDN | 20 | | ✖ | Obsolete |
| KEY | 25 | | ✔ | Obsolete |
| L32 | 105 | | ✖ | Obsolete |
| L64 | 106 | | ✖ | Obsolete |
| LP | 107 | | ✖ | Obsolete |
| MAILA | 254 | | ✖ | Obsolete |
| MAILB | 253 | | ✖ | Obsolete |
| MB | 7 | RFC 883 | ✖ | Obsolete |
| MD | 3 | RFC 883 | ✖ | Obsolete |
| MF | 4 | | ✖ | Obsolete |
| MG | 8 | | ✖ | Obsolete |
| MINFO | 14 | | ✖ | Obsolete |
| MR | 9 | | ✖ | Obsolete |
| NB | 32 | RFC 1002 | ✖ | Obsolete |
| NBSTAT | 33 | | ✖ | Obsolete |
| NID | 104 | RFC 6742 | ✖ | Obsolete |
| NIMLOC | 32 | N/A | ✖ | Obsolete |
| NINFO | 56 | N/A | ✖ | Obsolete |
| NSAP | 22 | RFC 1706 | ✖ | Obsolete |
| NSAP\-PTR | 23 | | ✖ | Obsolete |
| NULL | 10 | RFC 883 | ✖ | Obsolete |
| NXT | 30 | RFC 2065 | ✖ | Obsolete |
| PX | 26 | RFC 2163 | ✖ | Obsolete |
| RKEY | 57 | N/A | ✖ | Obsolete |
| RP | 17 | RFC 1183 | ✔ | Obsolete |
| RT | 21 | | ✖ | Obsolete |
| SIG | 24 | | ✔ | Obsolete |
| SINK | 40 | N/A | ✖ | Obsolete |
| SPF | 99 | RFC 4408 | ✔ | Obsolete |
| TALINK | 58 | N/A | ✖ | Obsolete |
| UID | 101 | N/A | ✖ | Obsolete |
| UINFO | 100 | N/A | ✖ | Obsolete |
| UNSPEC | 103 | N/A | ✖ | Obsolete |
| WKS | 11 | RFC 883 & RFC 1035 | ✖ | Obsolete |
| X25 | 19 | | ✖ | Obsolete |
_* Obsolescence based on [Wikipedia: List of DNS record types](https://en.wikipedia.org/wiki/List_of_DNS_record_types)_
\ No newline at end of file
<?php
declare(strict_types=1);
/*
* This file is part of Badcow DNS Library.
*
......@@ -11,9 +13,9 @@
namespace Badcow\DNS;
use Badcow\DNS\Parser\Tokens;
use Badcow\DNS\Rdata\A;
use Badcow\DNS\Rdata\AAAA;
use Badcow\DNS\Rdata\APL;
use Badcow\DNS\Rdata\CNAME;
use Badcow\DNS\Rdata\DNAME;
use Badcow\DNS\Rdata\HINFO;
......@@ -28,12 +30,6 @@ use Badcow\DNS\Rdata\TXT;
class AlignedBuilder
{
const COMMENT_DELIMINATOR = '; ';
const MULTILINE_BEGIN = '(';
const MULTILINE_END = ')';
/**
* The order in which Resource Records should appear in a zone.
*
......@@ -75,7 +71,7 @@ class AlignedBuilder
}
if ($resourceRecord->getType() !== $current) {
$master .= PHP_EOL.self::COMMENT_DELIMINATOR.$resourceRecord->getType().' RECORDS'.PHP_EOL;
$master .= Tokens::LINE_FEED.Tokens::SEMICOLON.Tokens::SPACE.$resourceRecord->getType().' RECORDS'.Tokens::LINE_FEED;
$current = $resourceRecord->getType();
}
......@@ -88,7 +84,7 @@ class AlignedBuilder
);
$master .= self::generateComment($resourceRecord);
$master .= PHP_EOL;
$master .= Tokens::LINE_FEED;
}
return $master;
......@@ -96,9 +92,9 @@ class AlignedBuilder
private static function generateControlEntries(Zone $zone): string
{
$master = '$ORIGIN '.$zone->getName().PHP_EOL;
$master = '$ORIGIN '.$zone->getName().Tokens::LINE_FEED;
if (null !== $zone->getDefaultTtl()) {
$master .= '$TTL '.$zone->getDefaultTtl().PHP_EOL;
$master .= '$TTL '.$zone->getDefaultTtl().Tokens::LINE_FEED;
}
return $master;
......@@ -107,7 +103,7 @@ class AlignedBuilder
private static function generateComment(ResourceRecord $resourceRecord): string
{
if (null !== $resourceRecord->getComment()) {
return self::COMMENT_DELIMINATOR.$resourceRecord->getComment();
return Tokens::SEMICOLON.Tokens::SPACE.$resourceRecord->getComment();
}
return '';
......@@ -123,8 +119,8 @@ class AlignedBuilder
*/
public static function compareResourceRecords(ResourceRecord $a, ResourceRecord $b): int
{
$a_rdata = (null === $a->getRdata()) ? '' : $a->getRdata()->output();
$b_rdata = (null === $b->getRdata()) ? '' : $b->getRdata()->output();
$a_rdata = (null === $a->getRdata()) ? '' : $a->getRdata()->toText();
$b_rdata = (null === $b->getRdata()) ? '' : $b->getRdata()->toText();
if ($a->getType() === $b->getType()) {
return strcmp($a->getName().$a_rdata, $b->getName().$b_rdata);
......@@ -152,119 +148,12 @@ class AlignedBuilder
*/
private static function generateRdataOutput(RdataInterface $rdata, int $padding): string
{
if ($rdata instanceof SOA) {
return self::outputSoa($rdata, $padding);
}
if ($rdata instanceof APL) {
return self::outputApl($rdata, $padding);
}
if ($rdata instanceof LOC) {
return self::outputLoc($rdata, $padding);
}
return $rdata->output();
}
/**
* @param SOA $rdata
* @param int $padding
*
* @return string
*/
private static function outputSoa(SOA $rdata, int $padding): string
{
$vars = [
$rdata->getMname(),
$rdata->getRname(),
$rdata->getSerial(),
$rdata->getRefresh(),
$rdata->getRetry(),
$rdata->getExpire(),
$rdata->getMinimum(),
];
$longestVarLength = max(array_map('strlen', $vars));
return self::MULTILINE_BEGIN.PHP_EOL.
self::makeLine((string) $rdata->getMname(), 'MNAME', $longestVarLength, $padding).
self::makeLine((string) $rdata->getRname(), 'RNAME', $longestVarLength, $padding).
self::makeLine((string) $rdata->getSerial(), 'SERIAL', $longestVarLength, $padding).
self::makeLine((string) $rdata->getRefresh(), 'REFRESH', $longestVarLength, $padding).
self::makeLine((string) $rdata->getRetry(), 'RETRY', $longestVarLength, $padding).
self::makeLine((string) $rdata->getExpire(), 'EXPIRE', $longestVarLength, $padding).
self::makeLine((string) $rdata->getMinimum(), 'MINIMUM', $longestVarLength, $padding).
str_repeat(' ', $padding).self::MULTILINE_END;
}
/**
* @param APL $rdata
* @param int $padding
*
* @return string
*/
private static function outputApl(APL $rdata, int $padding): string
{
$blocks = explode(' ', $rdata->output());
$longestVarLength = max(array_map('strlen', $blocks));
$string = self::MULTILINE_BEGIN.PHP_EOL;
foreach ($blocks as $block) {
$string .= self::makeLine($block, null, $longestVarLength, $padding);
}
return $string.str_repeat(' ', $padding).self::MULTILINE_END;
}
/**
* @param LOC $rdata
* @param int $padding
*
* @return string
*/
private static function outputLoc(LOC $rdata, int $padding): string
{
$parts = [
$rdata->getLatitude(LOC::FORMAT_DMS),
$rdata->getLongitude(LOC::FORMAT_DMS),
sprintf('%.2fm', $rdata->getAltitude()),
sprintf('%.2fm', $rdata->getSize()),
sprintf('%.2fm', $rdata->getHorizontalPrecision()),
sprintf('%.2fm', $rdata->getVerticalPrecision()),
];
$longestVarLength = max(array_map('strlen', $parts));
return self::MULTILINE_BEGIN.PHP_EOL.
self::makeLine((string) $rdata->getLatitude(LOC::FORMAT_DMS), 'LATITUDE', $longestVarLength, $padding).
self::makeLine((string) $rdata->getLongitude(LOC::FORMAT_DMS), 'LONGITUDE', $longestVarLength, $padding).
self::makeLine(sprintf('%.2fm', $rdata->getAltitude()), 'ALTITUDE', $longestVarLength, $padding).
self::makeLine(sprintf('%.2fm', $rdata->getSize()), 'SIZE', $longestVarLength, $padding).
self::makeLine(sprintf('%.2fm', $rdata->getHorizontalPrecision()), 'HORIZONTAL PRECISION', $longestVarLength, $padding).
self::makeLine(sprintf('%.2fm', $rdata->getVerticalPrecision()), 'VERTICAL PRECISION', $longestVarLength, $padding).
str_repeat(' ', $padding).self::MULTILINE_END;
}
/**
* Returns a padded line with comment.
*
* @param string $text
* @param string $comment
* @param int $longestVarLength
* @param int $padding
*
* @return string
*/
private static function makeLine(string $text, ?string $comment, int $longestVarLength, int $padding): string
{
$output = str_repeat(' ', $padding).str_pad($text, $longestVarLength);
if (null !== $comment) {
$output .= ' '.self::COMMENT_DELIMINATOR.$comment;
$rdataFormatters = AlignedRdataFormatters::getRdataFormatters();
if (array_key_exists($rdata->getType(), $rdataFormatters)) {
return call_user_func($rdataFormatters[$rdata->getType()], $rdata, $padding);
}
return $output.PHP_EOL;
return $rdata->toText();
}
/**
......@@ -279,9 +168,9 @@ class AlignedBuilder
$name = $ttl = $type = 0;
foreach ($zone as $resourceRecord) {
$name = max($name, strlen($resourceRecord->getName()));
$ttl = max($ttl, strlen($resourceRecord->getTtl()));
$type = max($type, strlen($resourceRecord->getType()));
$name = max($name, strlen($resourceRecord->getName() ?? ''));
$ttl = max($ttl, strlen((string) $resourceRecord->getTtl()));
$type = max($type, strlen($resourceRecord->getType() ?? ''));