@@ -1494,7 +1494,7 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap): ?DOM
1494
1494
$ parentClassName = self ::getClassSynopsisFilename ($ parent );
1495
1495
$ includeElement = $ this ->createIncludeElement (
1496
1496
$ doc ,
1497
- "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class. $ parentClassName')/db:partintro/db:section/db:classsynopsis/db:fieldsynopsis[preceding-sibling::db:classsynopsisinfo[1][@role='comment' and text()='& Properties; ']])) "
1497
+ "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class. $ parentClassName')/db:partintro/db:section/db:classsynopsis/db:fieldsynopsis[preceding-sibling::db:classsynopsisinfo[1][@role='comment' and text()='Properties']])) "
1498
1498
);
1499
1499
$ classSynopsis ->appendChild ($ includeElement );
1500
1500
}
@@ -1512,7 +1512,7 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap): ?DOM
1512
1512
$ classSynopsis ->appendChild (new DOMText ("\n " ));
1513
1513
$ includeElement = $ this ->createIncludeElement (
1514
1514
$ doc ,
1515
- "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class. $ className')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[not(@role='procedural')] "
1515
+ "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class. $ className')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[not(@role='procedural')]) "
1516
1516
);
1517
1517
$ classSynopsis ->appendChild ($ includeElement );
1518
1518
}
@@ -1530,7 +1530,7 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap): ?DOM
1530
1530
$ classSynopsis ->appendChild (new DOMText ("\n " ));
1531
1531
$ includeElement = $ this ->createIncludeElement (
1532
1532
$ doc ,
1533
- "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class. $ className')/db:refentry/db:refsect1[@role='description']/descendant::db:destructorsynopsis[not(@role='procedural')] "
1533
+ "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class. $ className')/db:refentry/db:refsect1[@role='description']/descendant::db:destructorsynopsis[not(@role='procedural')]) "
1534
1534
);
1535
1535
$ classSynopsis ->appendChild ($ includeElement );
1536
1536
}
@@ -2440,7 +2440,113 @@ function generateClassSynopses(array $classMap): array {
2440
2440
*/
2441
2441
function replaceClassSynopses (string $ targetDirectory , array $ classMap ): array
2442
2442
{
2443
- throw new Exception ("Not yet implemented! " );
2443
+ $ classSynopses = [];
2444
+
2445
+ $ it = new RecursiveIteratorIterator (
2446
+ new RecursiveDirectoryIterator ($ targetDirectory ),
2447
+ RecursiveIteratorIterator::LEAVES_ONLY
2448
+ );
2449
+
2450
+ foreach ($ it as $ file ) {
2451
+ $ pathName = $ file ->getPathName ();
2452
+ if (!preg_match ('/\.xml$/i ' , $ pathName )) {
2453
+ continue ;
2454
+ }
2455
+
2456
+ $ xml = file_get_contents ($ pathName );
2457
+ if ($ xml === false ) {
2458
+ continue ;
2459
+ }
2460
+
2461
+ if (stripos ($ xml , "<classsynopsis " ) === false ) {
2462
+ continue ;
2463
+ }
2464
+
2465
+ $ replacedXml = getReplacedSynopsisXml ($ xml );
2466
+
2467
+ $ doc = new DOMDocument ();
2468
+ $ doc ->formatOutput = false ;
2469
+ $ doc ->preserveWhiteSpace = true ;
2470
+ $ doc ->validateOnParse = true ;
2471
+ $ success = $ doc ->loadXML ($ replacedXml );
2472
+ if (!$ success ) {
2473
+ echo "Failed opening $ pathName \n" ;
2474
+ continue ;
2475
+ }
2476
+
2477
+ $ classSynopsisElements = [];
2478
+ foreach ($ doc ->getElementsByTagName ("classsynopsis " ) as $ element ) {
2479
+ $ classSynopsisElements [] = $ element ;
2480
+ }
2481
+
2482
+ foreach ($ classSynopsisElements as $ classSynopsis ) {
2483
+ if (!$ classSynopsis instanceof DOMElement) {
2484
+ continue ;
2485
+ }
2486
+
2487
+ $ firstChild = $ classSynopsis ->firstElementChild ;
2488
+ if ($ firstChild === null ) {
2489
+ continue ;
2490
+ }
2491
+ $ firstChild = $ firstChild ->firstElementChild ;
2492
+ if ($ firstChild === null ) {
2493
+ continue ;
2494
+ }
2495
+ $ className = $ firstChild ->textContent ;
2496
+ if (!isset ($ classMap [$ className ])) {
2497
+ continue ;
2498
+ }
2499
+ $ classInfo = $ classMap [$ className ];
2500
+
2501
+ $ newClassSynopsis = $ classInfo ->getClassSynopsisElement ($ doc , $ classMap );
2502
+ if ($ newClassSynopsis === null ) {
2503
+ continue ;
2504
+ }
2505
+
2506
+ // Check if there is any change - short circuit if there is not any.
2507
+
2508
+ if (replaceAndCompareXmls ($ doc , $ classSynopsis , $ newClassSynopsis )) {
2509
+ continue ;
2510
+ }
2511
+
2512
+ // Return the updated XML
2513
+
2514
+ $ replacedXml = $ doc ->saveXML ();
2515
+
2516
+ $ replacedXml = preg_replace (
2517
+ [
2518
+ "/REPLACED-ENTITY-([A-Za-z0-9._{}%-]+?;)/ " ,
2519
+ "/<phpdoc:classref\s+xmlns:phpdoc= \"([a-z0-9.:\/]+) \"\s+xmlns= \"([a-z0-9.:\/]+) \"\s+xmlns:xi= \"([a-z0-9.:\/]+) \"\s+xml:id= \"([a-z0-9._-]+) \"\s*>/i " ,
2520
+ "/<phpdoc:classref\s+xmlns:phpdoc= \"([a-z0-9.:\/]+) \"\s+xmlns= \"([a-z0-9.:\/]+) \"\s+xmlns:xlink= \"([a-z0-9.:\/]+) \"\s+xmlns:xi= \"([a-z0-9.:\/]+) \"\s+xml:id= \"([a-z0-9._-]+) \"\s*>/i " ,
2521
+ ],
2522
+ [
2523
+ "&$1 " ,
2524
+ "<phpdoc:classref xml:id= \"$4 \" xmlns:phpdoc= \"$1 \" xmlns= \"$2 \" xmlns:xi= \"$4 \"> " ,
2525
+ "<phpdoc:classref xml:id= \"$5 \" xmlns:phpdoc= \"$1 \" xmlns= \"$2 \" xmlns:xlink= \"$3 \" xmlns:xi= \"$4 \"> " ,
2526
+ ],
2527
+ $ replacedXml
2528
+ );
2529
+
2530
+ $ classSynopses [$ pathName ] = $ replacedXml ;
2531
+ }
2532
+ }
2533
+
2534
+ return $ classSynopses ;
2535
+ }
2536
+
2537
+ function getReplacedSynopsisXml (string $ xml ): string
2538
+ {
2539
+ return preg_replace (
2540
+ [
2541
+ "/&([A-Za-z0-9._{}%-]+?;)/ " ,
2542
+ "/<(\/)*xi:([A-Za-z]+?)/ "
2543
+ ],
2544
+ [
2545
+ "REPLACED-ENTITY-$1 " ,
2546
+ "<$1XI$2 " ,
2547
+ ],
2548
+ $ xml
2549
+ );
2444
2550
}
2445
2551
2446
2552
/**
@@ -2489,7 +2595,7 @@ function replaceMethodSynopses(string $targetDirectory, array $funcMap, array $a
2489
2595
continue ;
2490
2596
}
2491
2597
2492
- $ replacedXml = preg_replace ( " /&([A-Za-z0-9._{}%-]+?;)/ " , " REPLACED-ENTITY-$1 " , $ xml );
2598
+ $ replacedXml = getReplacedSynopsisXml ( $ xml );
2493
2599
2494
2600
$ doc = new DOMDocument ();
2495
2601
$ doc ->formatOutput = false ;
@@ -2501,10 +2607,6 @@ function replaceMethodSynopses(string $targetDirectory, array $funcMap, array $a
2501
2607
continue ;
2502
2608
}
2503
2609
2504
- $ docComparator = new DOMDocument ();
2505
- $ docComparator ->preserveWhiteSpace = false ;
2506
- $ docComparator ->formatOutput = true ;
2507
-
2508
2610
$ methodSynopsisElements = [];
2509
2611
foreach ($ doc ->getElementsByTagName ("constructorsynopsis " ) as $ element ) {
2510
2612
$ methodSynopsisElements [] = $ element ;
@@ -2568,19 +2670,7 @@ function replaceMethodSynopses(string $targetDirectory, array $funcMap, array $a
2568
2670
2569
2671
// Check if there is any change - short circuit if there is not any.
2570
2672
2571
- $ xml1 = $ doc ->saveXML ($ methodSynopsis );
2572
- $ xml1 = preg_replace ("/&([A-Za-z0-9._{}%-]+?;)/ " , "REPLACED-ENTITY-$1 " , $ xml1 );
2573
- $ docComparator ->loadXML ($ xml1 );
2574
- $ xml1 = $ docComparator ->saveXML ();
2575
-
2576
- $ methodSynopsis ->parentNode ->replaceChild ($ newMethodSynopsis , $ methodSynopsis );
2577
-
2578
- $ xml2 = $ doc ->saveXML ($ newMethodSynopsis );
2579
- $ xml2 = preg_replace ("/&([A-Za-z0-9._{}%-]+?;)/ " , "REPLACED-ENTITY-$1 " , $ xml2 );
2580
- $ docComparator ->loadXML ($ xml2 );
2581
- $ xml2 = $ docComparator ->saveXML ();
2582
-
2583
- if ($ xml1 === $ xml2 ) {
2673
+ if (replaceAndCompareXmls ($ doc , $ methodSynopsis , $ newMethodSynopsis )) {
2584
2674
continue ;
2585
2675
}
2586
2676
@@ -2631,6 +2721,28 @@ function replaceMethodSynopses(string $targetDirectory, array $funcMap, array $a
2631
2721
return $ methodSynopses ;
2632
2722
}
2633
2723
2724
+ function replaceAndCompareXmls (DOMDocument $ doc , DOMElement $ originalSynopsis , DOMElement $ newSynopsis ): bool
2725
+ {
2726
+ $ docComparator = new DOMDocument ();
2727
+ $ docComparator ->preserveWhiteSpace = false ;
2728
+ $ docComparator ->formatOutput = true ;
2729
+
2730
+ $ xml1 = $ doc ->saveXML ($ originalSynopsis );
2731
+ $ xml1 = getReplacedSynopsisXml ($ xml1 );
2732
+ $ docComparator ->loadXML ($ xml1 );
2733
+ $ xml1 = $ docComparator ->saveXML ();
2734
+
2735
+ $ originalSynopsis ->parentNode ->replaceChild ($ newSynopsis , $ originalSynopsis );
2736
+
2737
+ $ xml2 = $ doc ->saveXML ($ newSynopsis );
2738
+ $ xml2 = getReplacedSynopsisXml ($ xml2 );
2739
+
2740
+ $ docComparator ->loadXML ($ xml2 );
2741
+ $ xml2 = $ docComparator ->saveXML ();
2742
+
2743
+ return $ xml1 === $ xml2 ;
2744
+ }
2745
+
2634
2746
function installPhpParser (string $ version , string $ phpParserDir ) {
2635
2747
$ lockFile = __DIR__ . "/PHP-Parser-install-lock " ;
2636
2748
$ lockFd = fopen ($ lockFile , 'w+ ' );
@@ -2715,13 +2827,12 @@ function initPhpParser() {
2715
2827
$ context ->forceRegeneration = isset ($ options ["f " ]) || isset ($ options ["force-regeneration " ]);
2716
2828
$ context ->forceParse = $ context ->forceRegeneration || $ printParameterStats || $ verify || $ generateClassSynopses || $ replaceClassSynopses || $ generateMethodSynopses || $ replaceMethodSynopses ;
2717
2829
2718
- $ targetClassSynopses = $ argv [$ optind + 1 ] ?? null ;
2719
- if ($ replaceClassSynopses && $ targetClassSynopses === null ) {
2830
+ $ targetSynopses = $ argv [$ argc - 1 ] ?? null ;
2831
+ if ($ replaceClassSynopses && $ targetSynopses === null ) {
2720
2832
die ("A target class synopsis directory must be provided for. \n" );
2721
2833
}
2722
2834
2723
- $ targetMethodSynopses = $ argv [$ optind + 1 + ($ targetClassSynopses !== null )] ?? null ;
2724
- if ($ replaceMethodSynopses && $ targetMethodSynopses === null ) {
2835
+ if ($ replaceMethodSynopses && $ targetSynopses === null ) {
2725
2836
die ("A target method synopsis directory must be provided. \n" );
2726
2837
}
2727
2838
@@ -2884,7 +2995,7 @@ function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc
2884
2995
}
2885
2996
2886
2997
if ($ replaceClassSynopses ) {
2887
- $ classSynopses = replaceClassSynopses ($ targetClassSynopses , $ classMap );
2998
+ $ classSynopses = replaceClassSynopses ($ targetSynopses , $ classMap );
2888
2999
2889
3000
foreach ($ classSynopses as $ filename => $ content ) {
2890
3001
if (file_put_contents ($ filename , $ content )) {
@@ -2912,7 +3023,7 @@ function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc
2912
3023
}
2913
3024
2914
3025
if ($ replaceMethodSynopses ) {
2915
- $ methodSynopses = replaceMethodSynopses ($ targetMethodSynopses , $ funcMap , $ aliasMap );
3026
+ $ methodSynopses = replaceMethodSynopses ($ targetSynopses , $ funcMap , $ aliasMap );
2916
3027
2917
3028
foreach ($ methodSynopses as $ filename => $ content ) {
2918
3029
if (file_put_contents ($ filename , $ content )) {
0 commit comments