# PDF Dropdown Backup Solution (When Directory Browsing Is Disabled)

This guide documents a fallback approach for the header PDF dropdown feature when server directory browsing for `/PDF/` is disabled.

## Overview

Current behavior in `header.js` attempts to fetch the artifact-level `PDF` folder and parse directory-listing HTML for `.pdf` links.

When browsing is disabled, that request usually returns `403` and no files can be discovered. The fallback is to provide PDF filenames via one of these sources:

1. A lightweight server endpoint (recommended)
2. A static manifest file inside each artifact `PDF` folder

Both approaches keep the button hidden when no PDFs are returned.

---

## Option A (Recommended): Server Endpoint

### 1. Create endpoint

Add a new file: `php/GetPdfList.php`

Example implementation:

```php
<?php
header('Content-Type: application/json');

$artifact = isset($_GET['artifact']) ? trim($_GET['artifact']) : '';
if ($artifact === '') {
    http_response_code(400);
    echo json_encode(['error' => 'Missing artifact']);
    exit;
}

// Base folder that contains all artifacts
$basePath = realpath(__DIR__ . '/..');
$targetPath = realpath($basePath . '/' . $artifact . '/PDF');

// Prevent path traversal and invalid targets
if ($targetPath === false || strpos($targetPath, $basePath) !== 0 || !is_dir($targetPath)) {
    echo json_encode(['files' => []]);
    exit;
}

$files = [];
foreach (scandir($targetPath) as $name) {
    if ($name === '.' || $name === '..') continue;
    if (is_file($targetPath . DIRECTORY_SEPARATOR . $name) && preg_match('/\\.pdf$/i', $name)) {
        $files[] = $name; // preserves server order from scandir (alphabetical)
    }
}

echo json_encode(['files' => $files]);
```

### 2. Add endpoint fallback in `header.js`

In the PDF initialization flow:

1. Keep existing directory-listing attempt first.
2. If it fails with `403` or returns zero results, call endpoint:

```js
var artifactName = artifactRootSegments[artifactRootSegments.length - 1];
var endpointUrl = '/resources/webhelp/php/GetPdfList.php?artifact=' + encodeURIComponent(artifactName);
```

Expected endpoint response:

```json
{
  "files": ["Guide.pdf", "Admin.pdf"]
}
```

Convert response to menu links:

```js
var pdfLinks = data.files.map(function(name) {
  return {
    name: name,
    url: new URL(pdfDirectoryPath + name, window.location.origin).toString()
  };
});
```

Then reuse existing menu renderer.

### 3. Validate

1. Disable directory browsing.
2. Open artifact home page.
3. Confirm endpoint returns JSON.
4. Confirm PDF icon appears.
5. Confirm click opens each PDF in a new tab.

---

## Option B: Static Manifest File (No Server Code)

If adding PHP is not possible, store a manifest in each artifact:

`/<artifact>/PDF/pdfs.json`

Example:

```json
{
  "files": [
    "CompliEditor User Guide.pdf",
    "CompliEditor Tagging Guide.pdf"
  ]
}
```

In `header.js` fallback:

1. Try directory-listing parse.
2. On failure, fetch `pdfDirectoryPath + 'pdfs.json'`.
3. Build menu from `files`.

This requires updating `pdfs.json` whenever PDFs are added/removed.

---

## Suggested Runtime Order

Use this order in the script:

1. Try directory listing (`GET /PDF/`) and parse HTML links
2. If that fails or yields none, try endpoint (`GetPdfList.php`)
3. If endpoint is unavailable, try manifest (`/PDF/pdfs.json`)
4. If all fail or no files, keep `#headerPdfButton` hidden

---

## Operational Notes

1. Keep `window.open(url, '_blank', 'noopener,noreferrer')` for each menu item.
2. Preserve returned order from the source (no client sort) to match your requirement.
3. Always sanitize/encode output if endpoint responses are used in HTML.
4. If security blocks directory browsing again, endpoint/manifest keeps feature working without UI changes.
