Skip to content
This repository was archived by the owner on Jul 31, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: php-actions/composer@v6
- uses: php-actions/phpstan@v3
with:
version: composer
working_dir: "src/usr/local/php/unraid-tailscale-utils"
- run: "vendor/bin/phpstan"

commitlint:
name: Commitlint
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Install dependencies
uses: "php-actions/composer@v6"
with:
dev: no
working_dir: "src/usr/local/php/unraid-tailscale-utils"

- id: build_files
run: |
mkdir release
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.DS_Store
._.DS_Store
.php-cs-fixer.cache
/vendor
vendor
1 change: 1 addition & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
->in(__DIR__)
->name('*.php')
->name('*.page')
->exclude(['vendor'])
;

$config = new PhpCsFixer\Config();
Expand Down
3 changes: 3 additions & 0 deletions composer
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

composer --working-dir src/usr/local/php/unraid-tailscale-utils/ "$@"
6 changes: 0 additions & 6 deletions composer.json

This file was deleted.

2 changes: 2 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ parameters:
- page
paths:
- src
excludePaths:
- */vendor/*
5 changes: 4 additions & 1 deletion src/usr/local/emhttp/plugins/tailscale/approve-nodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
namespace Tailscale;

require_once "include/common.php";
if ( ! isset($utils)) {
throw new \Exception("Utils not initialized.");
}

$localAPI = new LocalAPI();

foreach (array_slice($argv, 1) as $key => $value) {
Utils::logmsg("Tailnet lock: signing {$value}");
$utils->logmsg("Tailnet lock: signing {$value}");
$localAPI->postTkaSign($value);
}
9 changes: 7 additions & 2 deletions src/usr/local/emhttp/plugins/tailscale/daily.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';

require_once "{$docroot}/plugins/tailscale/include/common.php";
if ( ! defined(__NAMESPACE__ . '\PLUGIN_ROOT') || ! defined(__NAMESPACE__ . '\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}
$utils = new Utils(PLUGIN_NAME);

$tailscaleConfig = $tailscaleConfig ?? new Config();

Utils::run_task('Tailscale\System::notifyOnKeyExpiration');
Utils::run_task('Tailscale\System::refreshWebGuiCert');
$utils->run_task('Tailscale\System::notifyOnKeyExpiration');
$utils->run_task('Tailscale\System::refreshWebGuiCert');
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

namespace Tailscale;

use EDACerton\PluginUtils\Translator;

if ( ! defined(__NAMESPACE__ . '\PLUGIN_ROOT') || ! defined(__NAMESPACE__ . '\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}

$tr = $tr ?? new Translator(PLUGIN_ROOT);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify external dependency availability.

The translator initialization correctly uses PLUGIN_ROOT as a constructor argument. However, static analysis reports that EDACerton\PluginUtils\Translator class is not found, which suggests the external library may not be properly installed or available in the analysis environment.

Please verify that the EDACerton\PluginUtils package is properly defined and available:


🏁 Script executed:

#!/bin/bash
# Check if the external library is properly configured in composer.json
find . -name "composer.json" -exec echo "=== {} ===" \; -exec cat {} \;

# Check if autoload files exist
find . -name "autoload.php" -type f

# Look for the actual Translator class file
find . -name "Translator.php" -type f

Length of output: 965


Ensure the EDACerton\PluginUtils\Translator class is actually installed and autoloaded

It looks like your composer.json does declare "edacerton/plugin-utils": "^1.0", but no vendor/autoload.php or Translator.php file was found in the repo scan—so the package isn’t installed or pulled into your plugin. Please:

  • In your plugin’s root directory (e.g. src/usr/local/emhttp/plugins/tailscale):
    • Add or verify a composer.json that requires "edacerton/plugin-utils": "^1.0".
    • Run composer install to generate vendor/ and vendor/autoload.php.
  • Confirm that vendor/edacerton/plugin-utils/src/Translator.php exists.
  • Ensure your plugin bootstrap includes require_once PLUGIN_ROOT . '/vendor/autoload.php'; (or otherwise points to the correct autoloader).

Once the package is installed and autoloaded, the Translator class will be found and the static-analysis error will disappear.

🧰 Tools
🪛 PHPStan (2.1.15)

11-11: Instantiated class EDACerton\PluginUtils\Translator not found.
Learn more at https://phpstan.org/user-guide/discovering-symbols

(class.notFound)

🤖 Prompt for AI Agents
In src/usr/local/emhttp/plugins/tailscale/include/Pages/Dashboard.php at line
11, the Translator class from the EDACerton\PluginUtils package is not found
because the package is not installed or autoloaded. To fix this, ensure your
plugin's root directory has a composer.json requiring "edacerton/plugin-utils":
"^1.0", run composer install there to generate the vendor directory and autoload
files, verify that vendor/edacerton/plugin-utils/src/Translator.php exists, and
include require_once PLUGIN_ROOT . '/vendor/autoload.php'; in your plugin
bootstrap to load the package classes properly.


$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();

$tailscale_dashboard = "<tr><td>" . $tr->tr("tailscale_disabled") . "</td></tr>";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

namespace Tailscale;

$tr = $tr ?? new Translator();
use EDACerton\PluginUtils\Translator;

if ( ! defined(__NAMESPACE__ . '\PLUGIN_ROOT') || ! defined(__NAMESPACE__ . '\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}

$tr = $tr ?? new Translator(PLUGIN_ROOT);

function help_block(string $section, Translator $tr, string $header = "h3"): string
{
$title = $tr->tr("settings.{$section}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

namespace Tailscale;

use EDACerton\PluginUtils\Translator;

if ( ! defined(__NAMESPACE__ . '\PLUGIN_ROOT') || ! defined(__NAMESPACE__ . '\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}

$tr = $tr ?? new Translator(PLUGIN_ROOT);

$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();

if ( ! $tailscaleConfig->Enable) {
echo($tr->tr("tailscale_disabled"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

namespace Tailscale;

use EDACerton\PluginUtils\Translator;

if ( ! defined(__NAMESPACE__ . '\PLUGIN_ROOT') || ! defined(__NAMESPACE__ . '\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}

$tr = $tr ?? new Translator(PLUGIN_ROOT);

$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();

if ( ! $tailscaleConfig->Enable) {
echo($tr->tr("tailscale_disabled"));
Expand Down
8 changes: 7 additions & 1 deletion src/usr/local/emhttp/plugins/tailscale/include/Pages/Log.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
?>
<?php

$tr = $tr ?? new Tailscale\Translator();
use EDACerton\PluginUtils\Translator;

if ( ! defined('Tailscale\PLUGIN_ROOT') || ! defined('Tailscale\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}

$tr = $tr ?? new Translator(Tailscale\PLUGIN_ROOT);
Comment on lines +15 to +21
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consistent migration pattern to external library.

The migration from local Tailscale\Translator to external EDACerton\PluginUtils\Translator follows a consistent pattern with proper runtime checks for required constants.

However, PHPStan indicates the external class is not found, which suggests:

  1. The external dependency may not be properly installed
  2. PHPStan configuration may need updating to include the external library path

🏁 Script executed:

#!/bin/bash
# Check if composer dependencies are installed
ls -la src/usr/local/php/unraid-tailscale-utils/vendor/

# Verify the external Translator class exists
fd -name "Translator.php" src/usr/local/php/unraid-tailscale-utils/vendor/

Length of output: 459


#!/bin/bash

Locate all vendor directories in the repo

fd -t d vendor

Search for any PHP file named Translator.php

fd -t f Translator.php

Check for a composer.json in the plugin root

fd -t f composer.json src/usr/local/emhttp/plugins/tailscale


🏁 Script executed:

#!/bin/bash
set -e

echo "Finding all vendor directories in the repo:"
fd --type d vendor

echo
echo "Locating any Translator.php files in the repo:"
fd --type f Translator.php

echo
echo "Searching for composer.json files in the repo:"
fd --type f composer.json

Length of output: 460


Ensure external Translator dependency is installed and autoloaded by PHPStan

The migration to EDACerton\PluginUtils\Translator in src/usr/local/emhttp/plugins/tailscale/include/Pages/Log.php is correct and the runtime checks are in place. However, PHPStan errors indicate the external class isn’t found. Please:

  • Install the Composer dependencies for the PluginUtils library:
    cd src/usr/local/php/unraid-tailscale-utils
    composer install
  • Verify that src/usr/local/php/unraid-tailscale-utils/vendor/autoload.php exists.
  • Update your PHPStan configuration (e.g. phpstan.neon) to include that autoload file or add the library’s directory to autoload_directories.

After these steps, re-run PHPStan to confirm the Translator class resolves without errors.

🧰 Tools
🪛 PHPStan (2.1.15)

21-21: Instantiated class EDACerton\PluginUtils\Translator not found.
Learn more at https://phpstan.org/user-guide/discovering-symbols

(class.notFound)

🤖 Prompt for AI Agents
In src/usr/local/emhttp/plugins/tailscale/include/Pages/Log.php lines 15 to 21,
PHPStan cannot find the external EDACerton\PluginUtils\Translator class due to
missing or unconfigured dependencies. Fix this by running composer install in
src/usr/local/php/unraid-tailscale-utils to install the PluginUtils library
dependencies, ensure the vendor/autoload.php file exists there, and then update
your PHPStan configuration (phpstan.neon) to include this autoload file or add
the library directory to autoload_directories. Finally, re-run PHPStan to verify
the class is correctly recognized.


$log = '/var/log/tailscale.log';
$prev = '/var/log/tailscale-utils.log';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@

namespace Tailscale;

use EDACerton\PluginUtils\Translator;

$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
require_once "{$docroot}/plugins/tailscale/include/common.php";

if ( ! defined(__NAMESPACE__ . '\PLUGIN_ROOT') || ! defined(__NAMESPACE__ . '\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}

$tr = $tr ?? new Translator(PLUGIN_ROOT);

$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();
?>
<script>
$(function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

namespace Tailscale;

use EDACerton\PluginUtils\Translator;

if ( ! defined(__NAMESPACE__ . '\PLUGIN_ROOT') || ! defined(__NAMESPACE__ . '\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}

$tr = $tr ?? new Translator(PLUGIN_ROOT);
Comment on lines +7 to +11
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Excellent runtime validation and proper translator instantiation.

The runtime checks ensure that required constants are defined before proceeding, and the translator is properly instantiated with the PLUGIN_ROOT parameter. The null coalescing operator ensures the translator is only created if not already set.

However, static analysis indicates the Translator class may not be found. Please verify that the edacerton/plugin-utils dependency is properly installed:


🏁 Script executed:

#!/bin/bash
# Check if the dependency is properly defined in composer.json
find . -name "composer.json" -exec cat {} \; | jq '.require["edacerton/plugin-utils"]'

# Verify composer.lock exists and contains the dependency
if [ -f "composer.lock" ]; then
    jq '.packages[] | select(.name == "edacerton/plugin-utils")' composer.lock
fi

Length of output: 123


Install missing edacerton/plugin-utils dependency

  • src/usr/local/emhttp/plugins/tailscale/include/Pages/Settings.php references new Translator(PLUGIN_ROOT)
  • composer.json declares "edacerton/plugin-utils": "^1.0", but composer.lock does not include that package

Please run composer update (or composer require edacerton/plugin-utils) to ensure the Translator class is available at runtime.

🧰 Tools
🪛 PHPStan (2.1.15)

11-11: Instantiated class EDACerton\PluginUtils\Translator not found.
Learn more at https://phpstan.org/user-guide/discovering-symbols

(class.notFound)

🤖 Prompt for AI Agents
In src/usr/local/emhttp/plugins/tailscale/include/Pages/Settings.php lines 7 to
11, the Translator class from the edacerton/plugin-utils package is used but the
package is missing from composer.lock, causing potential runtime errors. To fix
this, run `composer require edacerton/plugin-utils` or `composer update` to
install the missing dependency and ensure the Translator class is available at
runtime.


$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();

if (( ! isset($var)) || ( ! isset($display))) {
echo("Missing required WebGUI variables");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

namespace Tailscale;

use EDACerton\PluginUtils\Translator;

if ( ! defined(__NAMESPACE__ . '\PLUGIN_ROOT') || ! defined(__NAMESPACE__ . '\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}

$tr = $tr ?? new Translator(PLUGIN_ROOT);

$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();

if ( ! $tailscaleConfig->Enable) {
echo($tr->tr("tailscale_disabled"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@

namespace Tailscale;

use EDACerton\PluginUtils\Translator;

$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
require_once "{$docroot}/plugins/tailscale/include/common.php";

if ( ! defined(__NAMESPACE__ . '\PLUGIN_ROOT') || ! defined(__NAMESPACE__ . '\PLUGIN_NAME')) {
throw new \RuntimeException("Common file not loaded.");
}

$tr = $tr ?? new Translator(PLUGIN_ROOT);

$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();

if ( ! $tailscaleConfig->Enable) {
echo($tr->tr("tailscale_disabled"));
Expand Down

This file was deleted.

Loading