Factory   F
last analyzed

Complexity

Total Complexity 60

Size/Duplication

Total Lines 583
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 47

Test Coverage

Coverage 99.04%

Importance

Changes 0
Metric Value
wmc 60
lcom 1
cbo 47
dl 0
loc 583
ccs 308
cts 311
cp 0.9904
rs 3.6
c 0
b 0
f 0

47 Methods

Rating   Name   Duplication   Size   Complexity  
A newRdataFromName() 0 10 2
A newRdataFromId() 0 4 1
A isTypeImplemented() 0 4 1
A isTypeCodeImplemented() 0 8 2
B textToRdataType() 0 40 7
A getRdataClassName() 0 4 1
A AAAA() 0 7 1
A A() 0 7 1
A CNAME() 0 7 1
A HINFO() 0 8 1
A MX() 0 8 1
A SOA() 0 13 1
A NS() 0 7 1
A TXT() 0 7 1
A SPF() 0 7 1
A DNAME() 0 7 1
A LOC() 0 12 1
A PTR() 0 7 1
A DNSKEY() 0 9 1
A DS() 0 10 1
A NSEC() 0 8 1
A RRSIG() 0 17 1
A SRV() 0 10 1
A APL() 0 14 3
A CAA() 0 9 1
A AFSDB() 0 8 1
A CDNSKEY() 0 9 1
A CDS() 0 10 1
A CERT() 0 10 1
A CSYNC() 0 9 1
A DHCID() 0 19 4
A DLV() 0 10 1
A HIP() 0 10 1
A IPSECKEY() 0 9 1
A KEY() 0 10 1
A KX() 0 8 1
A NAPTR() 0 12 1
A NSEC3() 0 12 1
A NSEC3PARAM() 0 10 1
A RP() 0 8 1
A SIG() 0 17 1
A SSHFP() 0 9 1
A TA() 0 10 1
A TKEY() 0 13 1
A TLSA() 0 10 1
A TSIG() 0 13 1
A URI() 0 9 1

How to fix   Complexity   

Complex Class

Complex classes like Factory often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Factory, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Badcow DNS Library.
7
 *
8
 * (c) Samuel Williams <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Badcow\DNS\Rdata;
15
16
use Badcow\DNS\Parser\ParseException;
17
use Badcow\DNS\Parser\Tokens;
18
use PhpIP\IPBlock;
19
20
class Factory
21
{
22
    /**
23
     * Creates a new RData object from a name.
24
     *
25
     * @throws UnsupportedTypeException
26
     */
27 37
    public static function newRdataFromName(string $name): RdataInterface
28
    {
29 37
        if (!self::isTypeImplemented($name)) {
30 1
            throw new UnsupportedTypeException($name);
31
        }
32
33 36
        $className = self::getRdataClassName($name);
34
35 36
        return new $className();
36
    }
37
38
    /**
39
     * @throws UnsupportedTypeException
40
     */
41 11
    public static function newRdataFromId(int $id): RdataInterface
42
    {
43 11
        return self::newRdataFromName(Types::getName($id));
44
    }
45
46 39
    public static function isTypeImplemented(string $name): bool
47
    {
48 39
        return class_exists(self::getRdataClassName($name));
49
    }
50
51 3
    public static function isTypeCodeImplemented(int $typeCode): bool
52
    {
53
        try {
54 3
            return self::isTypeImplemented(Types::getName($typeCode));
55 2
        } catch (UnsupportedTypeException $e) {
56 2
            return false;
57
        }
58
    }
59
60
    /**
61
     * @throws ParseException|UnsupportedTypeException
62
     */
63 28
    public static function textToRdataType(string $type, string $text): RdataInterface
64
    {
65 28
        if (1 === preg_match('/^TYPE(\d+)$/', $type, $matches)) {
66 3
            $typeCode = (int) $matches[1];
67 3
            if (self::isTypeCodeImplemented($typeCode)) {
68 2
                $type = Types::getName($typeCode);
69
            } else {
70 2
                $rdata = new UnknownType();
71 2
                $rdata->fromText($text);
72 2
                $rdata->setTypeCode($typeCode);
73
74 2
                return $rdata;
75
            }
76
        }
77
78 27
        if (!self::isTypeImplemented($type)) {
79 2
            return new PolymorphicRdata($type, $text);
80
        }
81
82 25
        if (1 === preg_match('/^\\\#\s+(\d+)(\s[a-f0-9\s]+)?$/i', $text, $matches)) {
83 2
            if ('0' === $matches[1]) {
84
                $className = self::getRdataClassName($type);
85
86
                return new $className();
87
            }
88
89 2
            if (false === $wireFormat = hex2bin(str_replace(Tokens::SPACE, '', $matches[2]))) {
90
                throw new ParseException(sprintf('Unable to decode hexadecimal parameter in "%s".', $text));
91
            }
92 2
            $rdata = self::newRdataFromName($type);
93 2
            $rdata->fromWire($wireFormat);
94
95 2
            return $rdata;
96
        }
97
98 23
        $rdata = self::newRdataFromName($type);
99 23
        $rdata->fromText($text);
100
101 21
        return $rdata;
102
    }
103
104
    /**
105
     * Get the fully qualified class name of the RData class for $type.
106
     */
107 39
    public static function getRdataClassName(string $type): string
108
    {
109 39
        return __NAMESPACE__.'\\'.strtoupper($type);
110
    }
111
112
    /**
113
     * Create a new AAAA R-Data object.
114
     */
115 13
    public static function AAAA(string $address): AAAA
116
    {
117 13
        $rdata = new AAAA();
118 13
        $rdata->setAddress($address);
119
120 13
        return $rdata;
121
    }
122
123
    /**
124
     * Create a new A R-Data object.
125
     */
126 16
    public static function A(string $address): A
127
    {
128 16
        $rdata = new A();
129 16
        $rdata->setAddress($address);
130
131 16
        return $rdata;
132
    }
133
134
    /**
135
     * Create a new CNAME object.
136
     */
137 10
    public static function CNAME(string $cname): CNAME
138
    {
139 10
        $rdata = new CNAME();
140 10
        $rdata->setTarget($cname);
141
142 10
        return $rdata;
143
    }
144
145 10
    public static function HINFO(string $cpu, string $os): HINFO
146
    {
147 10
        $rdata = new HINFO();
148 10
        $rdata->setCpu($cpu);
149 10
        $rdata->setOs($os);
150
151 10
        return $rdata;
152
    }
153
154 12
    public static function MX(int $preference, string $exchange): MX
155
    {
156 12
        $rdata = new MX();
157 12
        $rdata->setPreference($preference);
158 12
        $rdata->setExchange($exchange);
159
160 12
        return $rdata;
161
    }
162
163 15
    public static function SOA(string $mname, string $rname, int $serial, int $refresh, int $retry, int $expire, int $minimum): SOA
164
    {
165 15
        $rdata = new SOA();
166 15
        $rdata->setMname($mname);
167 15
        $rdata->setRname($rname);
168 15
        $rdata->setSerial($serial);
169 15
        $rdata->setRefresh($refresh);
170 15
        $rdata->setRetry($retry);
171 15
        $rdata->setExpire($expire);
172 15
        $rdata->setMinimum($minimum);
173
174 15
        return $rdata;
175
    }
176
177 14
    public static function NS(string $nsdname): NS
178
    {
179 14
        $rdata = new NS();
180 14
        $rdata->setTarget($nsdname);
181
182 14
        return $rdata;
183
    }
184
185 11
    public static function TXT(string $text): TXT
186
    {
187 11
        $txt = new TXT();
188 11
        $txt->setText($text);
189
190 11
        return $txt;
191
    }
192
193 2
    public static function SPF(string $text): SPF
194
    {
195 2
        $spf = new SPF();
196 2
        $spf->setText($text);
197
198 2
        return $spf;
199
    }
200
201 10
    public static function DNAME(string $target): DNAME
202
    {
203 10
        $rdata = new DNAME();
204 10
        $rdata->setTarget($target);
205
206 10
        return $rdata;
207
    }
208
209
    /**
210
     * @param float $alt
211
     * @param float $size
212
     * @param float $hp
213
     * @param float $vp
214
     */
215 11
    public static function LOC(float $lat, float $lon, $alt = 0.0, $size = 1.0, $hp = 10000.0, $vp = 10.0): LOC
216
    {
217 11
        $loc = new LOC();
218 11
        $loc->setLatitude($lat);
219 11
        $loc->setLongitude($lon);
220 11
        $loc->setAltitude($alt);
221 11
        $loc->setSize($size);
222 11
        $loc->setHorizontalPrecision($hp);
223 11
        $loc->setVerticalPrecision($vp);
224
225 11
        return $loc;
226
    }
227
228 2
    public static function PTR(string $target): PTR
229
    {
230 2
        $ptr = new PTR();
231 2
        $ptr->setTarget($target);
232
233 2
        return $ptr;
234
    }
235
236 1
    public static function DNSKEY(int $flags, int $algorithm, string $publicKey): DNSKEY
237
    {
238 1
        $rdata = new DNSKEY();
239 1
        $rdata->setFlags($flags);
240 1
        $rdata->setAlgorithm($algorithm);
241 1
        $rdata->setPublicKey($publicKey);
242
243 1
        return $rdata;
244
    }
245
246 1
    public static function DS(int $keyTag, int $algorithm, string $digest, int $digestType = DS::DIGEST_SHA1): DS
247
    {
248 1
        $rdata = new DS();
249 1
        $rdata->setKeyTag($keyTag);
250 1
        $rdata->setAlgorithm($algorithm);
251 1
        $rdata->setDigest($digest);
252 1
        $rdata->setDigestType($digestType);
253
254 1
        return $rdata;
255
    }
256
257 1
    public static function NSEC(string $nextDomainName, array $types): NSEC
258
    {
259 1
        $rdata = new NSEC();
260 1
        $rdata->setNextDomainName($nextDomainName);
261 1
        array_map([$rdata, 'addType'], $types);
262
263 1
        return $rdata;
264
    }
265
266 11
    public static function RRSIG(string $typeCovered, int $algorithm, int $labels, int $originalTtl,
267
                                    \DateTime $signatureExpiration, \DateTime $signatureInception, int $keyTag,
268
                                    string $signersName, string $signature): RRSIG
269
    {
270 11
        $rrsig = new RRSIG();
271 11
        $rrsig->setTypeCovered($typeCovered);
272 11
        $rrsig->setAlgorithm($algorithm);
273 11
        $rrsig->setLabels($labels);
274 11
        $rrsig->setOriginalTtl($originalTtl);
275 11
        $rrsig->setSignatureExpiration($signatureExpiration);
276 11
        $rrsig->setSignatureInception($signatureInception);
277 11
        $rrsig->setKeyTag($keyTag);
278 11
        $rrsig->setSignersName($signersName);
279 11
        $rrsig->setSignature($signature);
280
281 11
        return $rrsig;
282
    }
283
284 11
    public static function SRV(int $priority, int $weight, int $port, string $target): SRV
285
    {
286 11
        $rdata = new SRV();
287 11
        $rdata->setPriority($priority);
288 11
        $rdata->setWeight($weight);
289 11
        $rdata->setPort($port);
290 11
        $rdata->setTarget($target);
291
292 11
        return $rdata;
293
    }
294
295
    /**
296
     * @param IPBlock[] $includedRanges
297
     * @param IPBlock[] $excludedRanges
298
     */
299 2
    public static function APL(array $includedRanges = [], array $excludedRanges = []): APL
300
    {
301 2
        $rdata = new APL();
302
303 2
        foreach ($includedRanges as $ipBlock) {
304 2
            $rdata->addAddressRange($ipBlock, true);
305
        }
306
307 2
        foreach ($excludedRanges as $ipBlock) {
308 2
            $rdata->addAddressRange($ipBlock, false);
309
        }
310
311 2
        return $rdata;
312
    }
313
314 1
    public static function CAA(int $flag, string $tag, string $value): CAA
315
    {
316 1
        $rdata = new CAA();
317 1
        $rdata->setFlag($flag);
318 1
        $rdata->setTag($tag);
319 1
        $rdata->setValue($value);
320
321 1
        return $rdata;
322
    }
323
324 1
    public static function AFSDB(int $subType, string $hostname): AFSDB
325
    {
326 1
        $afsdb = new AFSDB();
327 1
        $afsdb->setSubType($subType);
328 1
        $afsdb->setHostname($hostname);
329
330 1
        return $afsdb;
331
    }
332
333 1
    public static function CDNSKEY(int $flags, int $algorithm, string $publicKey): CDNSKEY
334
    {
335 1
        $cdnskey = new CDNSKEY();
336 1
        $cdnskey->setFlags($flags);
337 1
        $cdnskey->setAlgorithm($algorithm);
338 1
        $cdnskey->setPublicKey($publicKey);
339
340 1
        return $cdnskey;
341
    }
342
343 1
    public static function CDS(int $keyTag, int $algorithm, string $digest, int $digestType = DS::DIGEST_SHA1): CDS
344
    {
345 1
        $cds = new CDS();
346 1
        $cds->setKeyTag($keyTag);
347 1
        $cds->setAlgorithm($algorithm);
348 1
        $cds->setDigest($digest);
349 1
        $cds->setDigestType($digestType);
350
351 1
        return $cds;
352
    }
353
354
    /**
355
     * @param int|string $certificateType
356
     */
357 1
    public static function CERT($certificateType, int $keyTag, int $algorithm, string $certificate): CERT
358
    {
359 1
        $cert = new CERT();
360 1
        $cert->setCertificateType($certificateType);
361 1
        $cert->setKeyTag($keyTag);
362 1
        $cert->setAlgorithm($algorithm);
363 1
        $cert->setCertificate($certificate);
364
365 1
        return $cert;
366
    }
367
368 1
    public static function CSYNC(int $soaSerial, int $flags, array $types): CSYNC
369
    {
370 1
        $csync = new CSYNC();
371 1
        $csync->setSoaSerial($soaSerial);
372 1
        $csync->setFlags($flags);
373 1
        array_map([$csync, 'addType'], $types);
374
375 1
        return $csync;
376
    }
377
378
    /**
379
     * @param string|null $digest         Set to &null if the $identifier and $fqdn are known
380
     * @param int         $identifierType 16-bit integer
381
     * @param string|null $identifier     This is ignored if $digest is not &null
382
     * @param string|null $fqdn           This is ignored if $digest is not &null
383
     */
384 4
    public static function DHCID(?string $digest, int $identifierType, ?string $identifier = null, ?string $fqdn = null): DHCID
385
    {
386 4
        $dhcid = new DHCID();
387 4
        if (null !== $digest) {
388 3
            $dhcid->setIdentifierType($identifierType);
389 3
            $dhcid->setDigest($digest);
390
391 3
            return $dhcid;
392
        }
393
394 4
        if (null === $identifier || null === $fqdn) {
395 1
            throw new \InvalidArgumentException('Identifier and FQDN cannot be null if digest is null.');
396
        }
397
398 3
        $dhcid->setIdentifier($identifierType, $identifier);
399 3
        $dhcid->setFqdn($fqdn);
400
401 3
        return $dhcid;
402
    }
403
404 1
    public static function DLV(int $keyTag, int $algorithm, string $digest, int $digestType = DS::DIGEST_SHA1): DLV
405
    {
406 1
        $rdata = new DLV();
407 1
        $rdata->setKeyTag($keyTag);
408 1
        $rdata->setAlgorithm($algorithm);
409 1
        $rdata->setDigest($digest);
410 1
        $rdata->setDigestType($digestType);
411
412 1
        return $rdata;
413
    }
414
415
    /**
416
     * @param string[] $rendezvousServers
417
     */
418 1
    public static function HIP(int $publicKeyAlgorithm, string $hostIdentityTag, string $publicKey, array $rendezvousServers): HIP
419
    {
420 1
        $hip = new HIP();
421 1
        $hip->setPublicKeyAlgorithm($publicKeyAlgorithm);
422 1
        $hip->setHostIdentityTag($hostIdentityTag);
423 1
        $hip->setPublicKey($publicKey);
424 1
        array_map([$hip, 'addRendezvousServer'], $rendezvousServers);
425
426 1
        return $hip;
427
    }
428
429
    /**
430
     * @param int         $precedence an 8-bit unsigned integer
431
     * @param string|null $gateway    either &null for no gateway, a fully qualified domain name, or an IPv4 or IPv6 address
432
     * @param int         $algorithm  either IPSECKEY::ALGORITHM_NONE, IPSECKEY::ALGORITHM_DSA, IPSECKEY::ALGORITHM_RSA, or IPSECKEY::ALGORITHM_ECDSA
433
     * @param string|null $publicKey  base64 encoded public key
434
     */
435 6
    public static function IPSECKEY(int $precedence, ?string $gateway, int $algorithm = 0, ?string $publicKey = null): IPSECKEY
436
    {
437 6
        $ipseckey = new IPSECKEY();
438 6
        $ipseckey->setPrecedence($precedence);
439 6
        $ipseckey->setGateway($gateway);
440 6
        $ipseckey->setPublicKey($algorithm, $publicKey);
441
442 6
        return $ipseckey;
443
    }
444
445 1
    public static function KEY(int $flags, int $protocol, int $algorithm, string $publicKey): KEY
446
    {
447 1
        $key = new KEY();
448 1
        $key->setFlags($flags);
449 1
        $key->setProtocol($protocol);
450 1
        $key->setAlgorithm($algorithm);
451 1
        $key->setPublicKey($publicKey);
452
453 1
        return $key;
454
    }
455
456 1
    public static function KX(int $preference, string $exchanger): KX
457
    {
458 1
        $kx = new KX();
459 1
        $kx->setPreference($preference);
460 1
        $kx->setExchanger($exchanger);
461
462 1
        return $kx;
463
    }
464
465 4
    public static function NAPTR(int $order, int $preference, string $flags, string $services, string $regexp, string $replacement): NAPTR
466
    {
467 4
        $naptr = new NAPTR();
468 4
        $naptr->setOrder($order);
469 4
        $naptr->setPreference($preference);
470 4
        $naptr->setFlags($flags);
471 4
        $naptr->setServices($services);
472 4
        $naptr->setRegexp($regexp);
473 4
        $naptr->setReplacement($replacement);
474
475 4
        return $naptr;
476
    }
477
478 2
    public static function NSEC3(bool $unsignedDelegationsCovered, int $iterations, string $salt, string $nextOwnerName, array $types): NSEC3
479
    {
480 2
        $nsec3 = new NSEC3();
481 2
        $nsec3->setUnsignedDelegationsCovered($unsignedDelegationsCovered);
482 2
        $nsec3->setIterations($iterations);
483 2
        $nsec3->setSalt($salt);
484 2
        $nsec3->setNextOwnerName($nextOwnerName);
485 2
        $nsec3->setTypes($types);
486 2
        $nsec3->calculateNextOwnerHash();
487
488 2
        return $nsec3;
489
    }
490
491 2
    public static function NSEC3PARAM(int $hashAlgorithm, int $flags, int $iterations, string $salt): NSEC3PARAM
492
    {
493 2
        $nsec3param = new NSEC3PARAM();
494 2
        $nsec3param->setHashAlgorithm($hashAlgorithm);
495 2
        $nsec3param->setFlags($flags);
496 2
        $nsec3param->setIterations($iterations);
497 2
        $nsec3param->setSalt($salt);
498
499 2
        return $nsec3param;
500
    }
501
502 2
    public static function RP(string $mboxDomain, string $txtDomain): RP
503
    {
504 2
        $rp = new RP();
505 2
        $rp->setMailboxDomainName($mboxDomain);
506 2
        $rp->setTxtDomainName($txtDomain);
507
508 2
        return $rp;
509
    }
510
511 1
    public static function SIG(string $typeCovered, int $algorithm, int $labels, int $originalTtl,
512
                                 \DateTime $signatureExpiration, \DateTime $signatureInception, int $keyTag,
513
                                 string $signersName, string $signature): SIG
514
    {
515 1
        $sig = new SIG();
516 1
        $sig->setTypeCovered($typeCovered);
517 1
        $sig->setAlgorithm($algorithm);
518 1
        $sig->setLabels($labels);
519 1
        $sig->setOriginalTtl($originalTtl);
520 1
        $sig->setSignatureExpiration($signatureExpiration);
521 1
        $sig->setSignatureInception($signatureInception);
522 1
        $sig->setKeyTag($keyTag);
523 1
        $sig->setSignersName($signersName);
524 1
        $sig->setSignature($signature);
525
526 1
        return $sig;
527
    }
528
529 5
    public static function SSHFP(int $algorithm, int $fpType, string $fingerprint): SSHFP
530
    {
531 5
        $sshfp = new SSHFP();
532 5
        $sshfp->setAlgorithm($algorithm);
533 3
        $sshfp->setFingerprintType($fpType);
534 1
        $sshfp->setFingerprint($fingerprint);
535
536 1
        return $sshfp;
537
    }
538
539 1
    public static function TA(int $keyTag, int $algorithm, string $digest, int $digestType = DS::DIGEST_SHA1): TA
540
    {
541 1
        $ta = new TA();
542 1
        $ta->setKeyTag($keyTag);
543 1
        $ta->setAlgorithm($algorithm);
544 1
        $ta->setDigest($digest);
545 1
        $ta->setDigestType($digestType);
546
547 1
        return $ta;
548
    }
549
550
    /**
551
     * @param string $keyData   binary string
552
     * @param string $otherData binary string
553
     */
554 1
    public static function TKEY(string $algorithm, \DateTime $inception, \DateTime $expiration, int $mode, int $error, string $keyData, string $otherData = ''): TKEY
555
    {
556 1
        $tkey = new TKEY();
557 1
        $tkey->setAlgorithm($algorithm);
558 1
        $tkey->setInception($inception);
559 1
        $tkey->setExpiration($expiration);
560 1
        $tkey->setMode($mode);
561 1
        $tkey->setError($error);
562 1
        $tkey->setKeyData($keyData);
563 1
        $tkey->setOtherData($otherData);
564
565 1
        return $tkey;
566
    }
567
568 1
    public static function TLSA(int $certificateUsage, int $selector, int $matchingType, string $certificateAssociationData): TLSA
569
    {
570 1
        $tlsa = new TLSA();
571 1
        $tlsa->setCertificateUsage($certificateUsage);
572 1
        $tlsa->setSelector($selector);
573 1
        $tlsa->setMatchingType($matchingType);
574 1
        $tlsa->setCertificateAssociationData($certificateAssociationData);
575
576 1
        return $tlsa;
577
    }
578
579 1
    public static function TSIG(string $algorithmName, \DateTime $timeSigned, int $fudge, string $mac, int $originalId, int $error, string $otherData): TSIG
580
    {
581 1
        $tsig = new TSIG();
582 1
        $tsig->setAlgorithmName($algorithmName);
583 1
        $tsig->setTimeSigned($timeSigned);
584 1
        $tsig->setFudge($fudge);
585 1
        $tsig->setMac($mac);
586 1
        $tsig->setOriginalId($originalId);
587 1
        $tsig->setError($error);
588 1
        $tsig->setOtherData($otherData);
589
590 1
        return $tsig;
591
    }
592
593 6
    public static function URI(int $priority, int $weight, string $target): URI
594
    {
595 6
        $uri = new URI();
596 6
        $uri->setPriority($priority);
597 4
        $uri->setWeight($weight);
598 2
        $uri->setTarget($target);
599
600 1
        return $uri;
601
    }
602
}
603