[DOC-CVS] [doc-base] master: Alert in xi:include fixups, block/warning against functional xi:fallback (#332)

[email protected] (alfsb via GitHub) Mon, 3 Aug 2026 14:47:41 +0000
Newsgroups php.doc.cvs
Message-ID <[email protected]>
Author: alfsb (alfsb)
Committer: GitHub (web-flow)
Pusher: alfsb
Date: 2026-08-03T11:47:38-03:00

Commit: https://github.com/php/doc-base/commit/3ab7300086096e2701dcc82e16cfa405cbb4b07e
Raw diff: https://github.com/php/doc-base/commit/3ab7300086096e2701dcc82e16cfa405cbb4b07e.diff

Alert in xi:include fixups, block/warning against functional xi:fallback (#332)

* Tofu in xi:include fixups, block/warning against functional xi:fallback
* Alert in xi:include fixups

Changed paths:
  M  configure.php
  M  scripts/broken.php


Diff:

diff --git a/configure.php b/configure.php
index 312aa2a5ab..1b0e8a19ba 100755
--- a/configure.php
+++ b/configure.php
@@ -771,11 +771,11 @@ function individual_xml_broken_check()
     }
 }
 
-echo "Expanding XIncludes... ";
+xinclude_no_fallback( $dom );
 
+echo "Expanding XIncludes... ";
 $total  = xinclude_run_byid( $dom );
 $total += xinclude_run_xpointer( $dom );
-
 if ( $total == 0 )
     echo "failed.\n";
 else
@@ -783,6 +783,31 @@ function individual_xml_broken_check()
 
 xinclude_residual_fixup( $dom );
 
+function xinclude_no_fallback( DOMDocument $dom )
+{
+    // Check if there is reachable <xi:fallback>s.
+    // Not permited in doc-en, warning on translations.
+
+    $xpath = new DOMXPath( $dom );
+    $xpath->registerNamespace( "xi" , "http://www.w3.org/2001/XInclude" );
+
+    $xifallbacks = $xpath->query( "//xi:fallback" );
+
+    if ( $xifallbacks->length > 0 )
+    {
+        if ( $GLOBALS['ac']['LANG'] == 'en' )
+        {
+            print "\n<xi:fallback> cause silent errors in all languages.\n";
+            print "Not allowed on doc-en.\n";
+            errors_are_bad( 1 );
+        }
+        else
+        {
+            print "Translation contains <xi:fallback>. Manual parts will be missing.\n";
+        }
+    }
+}
+
 function xinclude_run_byid( DOMDocument $dom )
 {
     // libxml does not implements the XInclude 1.1 feature,
@@ -792,8 +817,9 @@ function xinclude_run_byid( DOMDocument $dom )
     $xpath = new DOMXPath( $dom );
     $xpath->registerNamespace( "xi" , "http://www.w3.org/2001/XInclude" );
 
-    // Resolve xpointers via a precomputed map; on duplicate xml:ids, first wins.
+    // Collect IDs in one go. On duplicate xml:ids, first wins.
     // Avoids quadratic tree walks (~ 90% performance gain).
+
     $byId = [];
     foreach( $xpath->query( "//*[@xml:id]" ) as $node ) {
         $byId[$node->getAttribute("xml:id")] ??= $node;
@@ -873,7 +899,7 @@ function xinclude_residual_fixup( DOMDocument $dom )
     $fixups = 0;
     $hardfail = false;
 
-    dom_saveload( $dom , __DIR__ . "/temp/manual.err" );
+    dom_saveload( $dom , __DIR__ . "/temp/debug.xi" );
     $nodes = xinclude_residual_list( $dom );
 
     foreach( $nodes as $node )
@@ -881,14 +907,17 @@ function xinclude_residual_fixup( DOMDocument $dom )
         $fixup = null;
         $parent = $node->parentNode->nodeName;
         $target = $node->getAttribute("xpointer");
-        $alert = "[[[Failed XInclude '$target']]]";
+        $alert = "[[[Failed XInclude<!-- $target -->']]]";
 
         if ( $fixups === 0 )
-            echo "\nFailed XIncludes, manual parts will be missing. Unresolved xpointers:\n";
+            echo "\nFailed XIncludes, manual parts will be missing. Failed xpointer:\n";
 
         echo "- {$target}\n";
         $fixups++;
 
+        // Empty elements are bad in PhD, so filling with $alert.
+        // See https://github.com/php/phd/issues/181
+
         switch( $parent )
         {
             case "listitem":
@@ -897,13 +926,13 @@ function xinclude_residual_fixup( DOMDocument $dom )
                 $fixup = "";
                 break;
             case "refsect1":
-                $fixup = "<title>_</title><simpara>$alert</simpara>"; // https://github.com/php/phd/issues/181
+                $fixup = "<title>$alert</title><simpara>$alert</simpara>";
                 break;
             case "tbody":
                 $fixup = "<row><entry>$alert</entry></row>";
                 break;
             case "variablelist":
-                $fixup = "<varlistentry><term></term><listitem><simpara>$alert</simpara></listitem></varlistentry>";
+                $fixup = "<varlistentry><term>$alert</term><listitem><simpara>$alert</simpara></listitem></varlistentry>";
                 break;
             case "classsynopsis":
                 $fixup = "<classsynopsisinfo role='comment'>$alert</classsynopsisinfo>";
@@ -929,7 +958,7 @@ function xinclude_residual_fixup( DOMDocument $dom )
     unset( $nodes );
 
     if ( $fixups > 0 )
-        echo "Dumped file: temp/manual.err. Inspect residual xi:include tags in this file.\n\n";
+        echo "Dumped file: temp/debug.xi. Inspect residual xi:include tags in this file.\n\n";
 
     if ( $hardfail )
     {
diff --git a/scripts/broken.php b/scripts/broken.php
index 8d6c80b016..bf93a017a7 100644
--- a/scripts/broken.php
+++ b/scripts/broken.php
@@ -167,6 +167,17 @@ function testFile( string $filename , bool $checkDnt , bool $fragmentDir = false
         echo "\n";
         return;
     }
+
+    $xpath = new DOMXPath( $doc );
+    $xpath->registerNamespace( "xi" , "http://www.w3.org/2001/XInclude" );
+    $list = $xpath->query( "//xi:fallback" );
+    if ( $list->length > 0 )
+    {
+        echo "File contains functional <xi:fallback>.\n";
+        echo "  Issue: Manual parts will be missing.\n";
+        echo "  Path:  $filename\n";
+        echo "\n";
+    }
 }
 
 function testDir( string $dir , bool $checkDnt )