@@ -105,13 +105,13 @@ private function setPublicSuffix(PublicSuffix $publicSuffix): PublicSuffix
105
105
}
106
106
107
107
$ publicSuffix = $ this ->normalize ($ publicSuffix );
108
- $ publicSuffixContent = $ publicSuffix ->getContent ();
109
- if ($ this ->domain === $ publicSuffixContent ) {
110
- throw new Exception (sprintf ('The public suffix `%s` can not be equal to the domain name `%s` ' , $ publicSuffixContent , $ this ->domain ));
108
+ $ psContent = $ publicSuffix ->getContent ();
109
+ if ($ this ->domain === $ psContent ) {
110
+ throw new Exception (sprintf ('The public suffix `%s` can not be equal to the domain name `%s` ' , $ psContent , $ this ->domain ));
111
111
}
112
112
113
- if ('. ' .$ publicSuffixContent !== substr ($ this ->domain , - strlen ($ publicSuffixContent ) - 1 )) {
114
- throw new Exception (sprintf ('The public suffix `%s` can not be assign to the domain name `%s` ' , $ publicSuffixContent , $ this ->domain ));
113
+ if ('. ' .$ psContent !== substr ($ this ->domain , - strlen ($ psContent ) - 1 )) {
114
+ throw new Exception (sprintf ('The public suffix `%s` can not be assign to the domain name `%s` ' , $ psContent , $ this ->domain ));
115
115
}
116
116
117
117
return $ publicSuffix ;
@@ -193,6 +193,14 @@ public function getIterator()
193
193
* {@inheritdoc}
194
194
*/
195
195
public function jsonSerialize ()
196
+ {
197
+ return $ this ->__debugInfo ();
198
+ }
199
+
200
+ /**
201
+ * {@inheritdoc}
202
+ */
203
+ public function __debugInfo ()
196
204
{
197
205
return [
198
206
'domain ' => $ this ->domain ,
@@ -205,14 +213,6 @@ public function jsonSerialize()
205
213
];
206
214
}
207
215
208
- /**
209
- * {@inheritdoc}
210
- */
211
- public function __debugInfo ()
212
- {
213
- return $ this ->jsonSerialize ();
214
- }
215
-
216
216
/**
217
217
* {@inheritdoc}
218
218
*/
@@ -433,18 +433,52 @@ public function withSubDomain($subDomain): self
433
433
throw new Exception ('A subdomain can not be added to a domain without a public suffix part. ' );
434
434
}
435
435
436
- if (!$ subDomain instanceof PublicSuffix) {
437
- $ subDomain = new PublicSuffix ($ subDomain );
436
+ $ subDomain = $ this ->filterSubDomain ($ subDomain );
437
+ $ subLabels = [];
438
+ if (null !== $ subDomain ) {
439
+ static $ pattern = '/[^\x20-\x7f]/ ' ;
440
+ $ method = !preg_match ($ pattern , $ this ->domain ) ? 'idnToAscii ' : 'idnToUnicode ' ;
441
+
442
+ $ subDomain = $ this ->$ method ($ subDomain );
443
+ $ subLabels = array_reverse (explode ('. ' , $ subDomain ));
438
444
}
439
445
440
- $ subDomain = $ this ->normalize ($ subDomain );
441
- if ($ this ->subDomain === $ subDomain ->getContent ()) {
446
+ if ($ this ->subDomain === $ subDomain ) {
442
447
return $ this ;
443
448
}
444
449
445
- $ labels = array_merge (array_slice ($ this ->labels , 0 , count ($ this ->publicSuffix ) + 1 ), iterator_to_array ($ subDomain ));
450
+ $ labels = array_merge (
451
+ array_slice ($ this ->labels , 0 , count ($ this ->publicSuffix ) + 1 ),
452
+ $ subLabels
453
+ );
454
+
455
+ return new self (implode ('. ' , array_reverse ($ labels )), $ this ->publicSuffix );
456
+ }
457
+
458
+ /**
459
+ * Filter a subdomain to update the domain part.
460
+ *
461
+ * @param mixed $subDomain
462
+ *
463
+ * @throws TypeError if the sub domain can not be converted
464
+ *
465
+ * @return string|null
466
+ */
467
+ private function filterSubDomain ($ subDomain )
468
+ {
469
+ if ($ subDomain instanceof DomainInterface) {
470
+ return $ subDomain ->getContent ();
471
+ }
472
+
473
+ if (null === $ subDomain ) {
474
+ return $ subDomain ;
475
+ }
476
+
477
+ if (is_scalar ($ subDomain ) || method_exists ($ subDomain , '__toString ' )) {
478
+ return (string ) $ subDomain ;
479
+ }
446
480
447
- return new self ( implode ( ' . ' , array_reverse ( array_values ( $ labels ))), $ this -> publicSuffix );
481
+ throw new TypeError ( sprintf ( ' The label must be a scalar, a stringable object or NULL, `%s` given ' , gettype ( $ subDomain )) );
448
482
}
449
483
450
484
/**
@@ -461,22 +495,53 @@ public function withSubDomain($subDomain): self
461
495
*/
462
496
public function withPublicSuffix ($ publicSuffix ): self
463
497
{
464
- if (!$ publicSuffix instanceof PublicSuffix) {
465
- $ publicSuffix = new PublicSuffix ($ publicSuffix );
466
- }
467
-
468
498
if (null === $ this ->publicSuffix ->getContent ()) {
469
499
throw new Exception ('A public suffix can not be added to a domain without a public suffix part. ' );
470
500
}
471
501
502
+ if (!$ publicSuffix instanceof PublicSuffix) {
503
+ $ publicSuffix = new PublicSuffix ($ publicSuffix );
504
+ }
505
+
472
506
$ publicSuffix = $ this ->normalize ($ publicSuffix );
473
507
if ($ this ->publicSuffix == $ publicSuffix ) {
474
508
return $ this ;
475
509
}
476
510
477
- $ labels = array_merge (iterator_to_array ($ publicSuffix ), array_slice ($ this ->labels , count ($ this ->publicSuffix )));
511
+ $ labels = array_merge (
512
+ iterator_to_array ($ publicSuffix ),
513
+ array_slice ($ this ->labels , count ($ this ->publicSuffix ))
514
+ );
478
515
479
- return new self (implode ('. ' , array_reverse (array_values ($ labels ))), $ publicSuffix );
516
+ return new self (implode ('. ' , array_reverse ($ labels )), $ publicSuffix );
517
+ }
518
+
519
+ /**
520
+ * Appends a label to the domain.
521
+ *
522
+ * @see ::withLabel
523
+ *
524
+ * @param mixed $label
525
+ *
526
+ * @return self
527
+ */
528
+ public function prepend ($ label ): self
529
+ {
530
+ return $ this ->withLabel (count ($ this ->labels ), $ label );
531
+ }
532
+
533
+ /**
534
+ * Prepends a label to the domain.
535
+ *
536
+ * @see ::withLabel
537
+ *
538
+ * @param mixed $label
539
+ *
540
+ * @return self
541
+ */
542
+ public function append ($ label ): self
543
+ {
544
+ return $ this ->withLabel (- count ($ this ->labels ) - 1 , $ label );
480
545
}
481
546
482
547
/**
@@ -498,40 +563,33 @@ public function withPublicSuffix($publicSuffix): self
498
563
*/
499
564
public function withLabel (int $ key , $ label ): self
500
565
{
501
- if (null === $ label ) {
502
- throw new TypeError ('The label must be a scalar or a stringable object `NULL` given ' );
503
- }
504
-
505
- if (!$ label instanceof Domain) {
506
- $ label = new Domain ($ label );
507
- }
508
-
509
566
$ nb_labels = count ($ this ->labels );
510
- $ offset = filter_var ($ key , FILTER_VALIDATE_INT , ['options ' => ['min_range ' => - $ nb_labels - 1 , 'max_range ' => $ nb_labels ]]);
511
- if (false === $ offset ) {
567
+ if ($ key < - $ nb_labels - 1 || $ key > $ nb_labels ) {
512
568
throw new Exception (sprintf ('the given key `%s` is invalid ' , $ key ));
513
569
}
514
570
515
- if (0 > $ offset ) {
516
- $ offset = $ nb_labels + $ offset ;
571
+ if (0 > $ key ) {
572
+ $ key = $ nb_labels + $ key ;
517
573
}
518
574
519
- if (( $ this -> labels [ $ offset ] ?? null ) === ( string ) $ label ) {
520
- return $ this ;
575
+ if (! is_scalar ( $ label ) && ! method_exists ( $ label, ' __toString ' ) ) {
576
+ throw new TypeError ( sprintf ( ' The label must be a scalar or a stringable object `%s` given ' , gettype ( $ label ))) ;
521
577
}
522
578
523
- if (null !== $ this ->domain ) {
524
- static $ pattern = '/[^\x20-\x7f]/ ' ;
525
- $ label = !preg_match ($ pattern , $ this ->domain ) ? $ label ->toAscii () : $ label ->toUnicode ();
579
+ static $ pattern = '/[^\x20-\x7f]/ ' ;
580
+ $ method = !preg_match ($ pattern , $ this ->domain ) ? 'idnToAscii ' : 'idnToUnicode ' ;
581
+ $ label = $ this ->$ method ((string ) $ label );
582
+ if (($ this ->labels [$ key ] ?? null ) === $ label ) {
583
+ return $ this ;
526
584
}
527
585
528
586
$ labels = $ this ->labels ;
529
- $ labels [$ offset ] = ( string ) $ label ;
587
+ $ labels [$ key ] = $ label ;
530
588
ksort ($ labels );
531
589
532
590
return new self (
533
- implode ('. ' , array_reverse (array_values ( $ labels) )),
534
- null === $ this ->publicSuffix ->getLabel ($ offset ) ? $ this ->publicSuffix : null
591
+ implode ('. ' , array_reverse ($ labels )),
592
+ null === $ this ->publicSuffix ->getLabel ($ key ) ? $ this ->publicSuffix : null
535
593
);
536
594
}
537
595
@@ -551,25 +609,23 @@ public function withLabel(int $key, $label): self
551
609
*
552
610
* @return self
553
611
*/
554
- public function withoutLabels (int $ key , int ...$ keys ): self
612
+ public function withoutLabel (int $ key , int ...$ keys ): self
555
613
{
556
614
array_unshift ($ keys , $ key );
557
615
$ nb_labels = count ($ this ->labels );
558
- $ options = ['options ' => ['min_range ' => - $ nb_labels , 'max_range ' => $ nb_labels - 1 ]];
559
- $ mapper = function (int $ key ) use ($ options , $ nb_labels ): int {
560
- if (false === ($ offset = filter_var ($ key , FILTER_VALIDATE_INT , $ options ))) {
616
+ $ mapper = function (int $ key ) use ($ nb_labels ): int {
617
+ if (- $ nb_labels > $ key || $ nb_labels - 1 < $ key ) {
561
618
throw new Exception (sprintf ('the key `%s` is invalid ' , $ key ));
562
619
}
563
620
564
- if (0 > $ offset ) {
565
- return $ nb_labels + $ offset ;
621
+ if (0 > $ key ) {
622
+ return $ nb_labels + $ key ;
566
623
}
567
624
568
- return $ offset ;
625
+ return $ key ;
569
626
};
570
627
571
628
$ deleted_keys = array_keys (array_count_values (array_map ($ mapper , $ keys )));
572
-
573
629
$ filter = function ($ key ) use ($ deleted_keys ): bool {
574
630
return !in_array ($ key , $ deleted_keys , true );
575
631
};
@@ -580,11 +636,8 @@ public function withoutLabels(int $key, int ...$keys): self
580
636
}
581
637
582
638
$ domain = implode ('. ' , array_reverse (array_values ($ labels )));
583
- $ publicSuffixContent = $ this ->publicSuffix ->getContent ();
584
-
585
- if (null === $ publicSuffixContent ||
586
- '. ' .$ publicSuffixContent !== substr ($ domain , - strlen ($ publicSuffixContent ) - 1 )
587
- ) {
639
+ $ psContent = $ this ->publicSuffix ->getContent ();
640
+ if (null === $ psContent || '. ' .$ psContent !== substr ($ domain , - strlen ($ psContent ) - 1 )) {
588
641
return new self ($ domain );
589
642
}
590
643
0 commit comments