Silverstripe代码验证服务

一个实时验证AI助手生成的Silverstripe 6 PHP代码的服务,用于捕获从Silverstripe 5到6的常见迁移问题。

  • by sandervanscheepen
  • PHP
  • 本地部署
  • 5 星标
  • 更新于
在 GitHub 查看 sandervanscheepen/silverstripe-mcp

使用说明

Silverstripe MCP服务器

A. 模型上下文协议 当AI助手生成Silverstripe 6 PHP代码时,提供实时验证反馈的服务器。在从Silverstripe 5到6的常见迁移问题到达您的代码库之前捕获它们。

文档: 建筑 | 代理指令设置

问题

当在Silverstripe 6项目中使用Claude Code等AI编码助手时,它们通常会生成具有过时模式的代码:

// AI generates this (SS5 style):
use SilverStripe\ORM\ArrayList;
use SilverStripe\View\ArrayData;

class MyTask extends BuildTask {
    public function run(HTTPRequest $request) {
        echo "Processing...";
    }
}

此MCP服务器会立即发现这些问题,使AI能够自我纠正:

// After validation, AI generates this (SS6 style):
use SilverStripe\Model\List\ArrayList;
use SilverStripe\Model\ArrayData;

class MyTask extends BuildTask {
    protected static string $commandName = 'my-task';

    protected function execute(InputInterface $input, PolyOutput $output): int {
        $output->writeln('Processing...');
        return Command::SUCCESS;
    }
}

运作原理

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  AI generates   │────▶│  MCP validates  │────▶│  AI fixes and   │
│  PHP code       │     │  against SS6    │     │  re-validates   │
└─────────────────┘     └─────────────────┘     └─────────────────┘
                               │
                               ▼
                        ┌─────────────────┐
                        │  PHP Analyzer   │
                        │  (AST-based)    │
                        └─────────────────┘
                               │
                   ┌───────────┴───────────┐
                   ▼                       ▼
            ┌─────────────┐         ┌─────────────┐
            │  Namespace  │         │  BuildTask  │
            │  Validator  │         │  Validator  │
            └─────────────┘         └─────────────┘

服务器公开了一个 ss-validator 该工具:

  1. 将PHP代码解析为抽象语法树(AST)
  2. 对代码运行基于插件的验证器
  3. 返回行号问题和建议修复
  4. AI迭代,直到没有问题为止

快速开始

安装

git clone https://github.com/sandervanscheepen/silverstripe-mcp
cd silverstripe-mcp

# Install dependencies
npm install
cd php && composer install && cd ..

# Build
npm run build

然后添加到您的MCP客户端(例如,Claude Code):

claude mcp add silverstripe-mcp -- node /path/to/silverstripe-mcp/dist/index.js

或者添加到您的MCP客户端配置文件中:

{
  "mcpServers": {
    "silverstripe": {
      "command": "node",
      "args": ["/path/to/silverstripe-mcp/dist/index.js"]
    }
  }
}

代理指令设置

为了充分利用此MCP服务器,请在AI代理的项目指令文件中添加指令(例如。, CLAUDE.md, .cursorrules, .github/copilot-instructions.md)告诉它使用 ss-validator 工具上所有生成的PHP代码。看 推荐代理说明 对于完整、最小和特定于项目的模板,您可以将其复制到项目中。

内置验证器

命名空间验证器

检测过时的Silverstripe 5导入,并建议其Silverstripe 6等效物:

SS5命名空间 SS6命名空间
SilverStripe\ORM\ArrayList SilverStripe\Model\List\ArrayList
SilverStripe\ORM\PaginatedList SilverStripe\Model\List\PaginatedList
SilverStripe\ORM\Map SilverStripe\Model\List\Map
SilverStripe\ORM\GroupedList SilverStripe\Model\List\GroupedList
SilverStripe\View\ArrayData SilverStripe\Model\ArrayData
SilverStripe\View\ViewableData SilverStripe\Model\ModelData
SilverStripe\ORM\ValidationResult SilverStripe\Core\Validation\ValidationResult
SilverStripe\ORM\ValidationException SilverStripe\Core\Validation\ValidationException

构建任务验证器

检测需要迁移到PolyCommand的旧BuildTask模式:

问题 检测 建议
弃用的方法签名 run(HTTPRequest $request) execute(InputInterface $input, PolyOutput $output): int
缺少命令名 否 $commandName 财产 protected static string $commandName = 'my-task';
通过回声输出 echo "..." $output->writeln('...')
通过打印输出 print "..." $output->writeln('...')

FormField值验证器

检测以下内容的使用情况 FormField::Value() 在SS6中分为三种方法:

// Detects this:
$value = $field->Value();

// Suggests using one of:
$value = $field->dataValue();       // Raw data value
$value = $field->presentedValue();  // Value for display
$value = $field->processedValue();  // Value after form processing

已删除方法验证器

检测对Silverstripe 6中删除的方法的调用:

删除方法 建议
Controller::has_curr() 使用 Controller::curr() 用try/catch
DataObject::getCMSValidator() 使用 getCMSCompositeValidator() 相反
Requirements::themedCSS() 使用 Requirements::css() 使用ThemeResourceLoader
Requirements::themedJavascript() 使用 Requirements::javascript() 使用ThemeResourceLoader
Object::useCustomClass() 改用喷油器配置

不推荐配置API(deprecated-config)

检测弃用的使用情况 Config::inst()->get() 图案:

// Detects this:
$value = Config::inst()->get('SilverStripe\CMS\Model\SiteTree', 'allowed_children');

// Suggests this:
$value = SiteTree::config()->get('allowed_children');

上下文感知验证器

以下验证器根据代码上下文自动启用,在分析不需要它们的代码时将开销降至最低:

延长钩可见性(extension-hook-visibility)

在以下情况下自动启用: 类扩展 Extension, DataExtension,或 SiteTreeExtension

SS6改变了许多延长钩方法 protected.检测扩展类中的公共钩子:

class MyExtension extends DataExtension {
    // Detects: should be protected
    public function onBeforeWrite() { }
    public function updateCMSFields($fields) { }
}

可配置前缀: onBefore, onAfter, update, augment (通过添加更多 additionalPrefixes).

元素命名空间(elemental-namespace)

在以下情况下自动启用: 任何导入都以开头 DNADesign\Elemental

对于使用 dnadesign/silverstripe-elemental。检测Elemental 6中的命名空间更改:

SS5命名空间 SS6命名空间
DNADesign\Elemental\TopPage\DataExtension DNADesign\Elemental\Extensions\TopPageElementExtension
DNADesign\Elemental\TopPage\FluentExtension DNADesign\Elemental\Extensions\TopPageFluentElementExtension
DNADesign\Elemental\TopPage\SiteTreeExtension DNADesign\Elemental\Extensions\TopPageSiteTreeExtension
DNADesign\Elemental\Controllers\ElementSiteTreeFilterSearch DNADesign\Elemental\ORM\Search\ElementalSiteTreeSearchContext

还可以检测已删除的类(GraphQL、ElementalLeft和MainExtension等)。

强制所有插件

要强制启用所有验证器,无论上下文如何:

通过配置(silverstripe-mcp.json):

{
  "enableAllPlugins": true
}

通过工具论证:

{
  "code": "<?php ...",
  "enableAllPlugins": true
}

您还可以显式启用单个自动插件始终运行:

{
  "plugins": {
    "elemental-namespace": {
      "enabled": true,
      "additionalMappings": {
        "Custom\\Old\\Class": "Custom\\New\\Class"
      }
    }
  }
}

配置

创建 silverstripe-mcp.json 在项目根目录中自定义行为:

{
  "phpBinary": "/path/to/php",
  "targetVersion": "6.0",
  "plugins": {
    "namespace-validator": {
      "enabled": true,
      "additionalMappings": {
        "App\\Legacy\\MyClass": "App\\Modern\\MyClass"
      }
    },
    "buildtask-validator": {
      "enabled": true
    },
    "deprecated-config": {
      "enabled": true
    },
    "extension-hook-visibility": {
      "enabled": true,
      "additionalPrefixes": ["can", "provide"]
    }
  },
  "customPlugins": [
    "./my-plugins/CustomValidator.php"
  ]
}

看 silverstripe-mcp.example.json 举一个完整的例子。

配置选项

选项 类型 描述
phpBinary string PHP 8.3+可执行文件的路径(如果未指定,则自动检测)
targetVersion string 要验证的Silverstripe版本(默认值: "6.0")
enableAllPlugins boolean 强制启用所有插件,包括上下文感知插件(默认: false)
plugins object 根据插件配置
plugins.*.enabled boolean 启用/禁用特定插件
plugins.namespace-validator.additionalMappings object 自定义命名空间迁移
customPlugins string[] 自定义验证器插件的路径

PHP二进制分辨率

服务器需要PHP 8.3+(Silverstripe 6的最低版本)。它按以下顺序解析PHP二进制文件:

  1. 配置文件: phpBinary 在 silverstripe-mcp.json
  2. 环境变量: PHP_BINARY (如果版本>=8.3)
  3. 自动检测:常见位置(Laragon、XAMPP、Homebrew、系统路径)
  4. 系统PHP:回落到 php 命令(如果版本>=8.3)

如果您的系统PHP低于8.3,请在配置中指定路径:

{
  "phpBinary": "C:/laragon/bin/php/php-8.3.22-Win32-vs16-x64/php.exe"
}

或设置 PHP_BINARY MCP客户端配置中的环境变量:

{
  "mcpServers": {
    "silverstripe": {
      "command": "node",
      "args": ["/path/to/silverstripe-mcp/dist/index.js"],
      "env": {
        "PHP_BINARY": "/usr/local/bin/php8.3"
      }
    }
  }
}

编写自定义插件

创建一个PHP类来实现 ValidatorPluginInterface:

<?php

namespace MyOrg\MCPPlugins;

use SilverstripeMCP\Contracts\ValidatorPluginInterface;
use SilverstripeMCP\AnalysisContext;
use SilverstripeMCP\Issue;
use PhpParser\NodeVisitorAbstract;
use PhpParser\Node;

class DeprecatedMethodPlugin implements ValidatorPluginInterface
{
    public function getName(): string
    {
        return 'deprecated-method-validator';
    }

    public function getDescription(): string
    {
        return 'Detects usage of deprecated methods';
    }

    public function getTargetVersions(): array
    {
        return ['6.*']; // Applies to all SS6.x versions
    }

    public function configure(array $options): void
    {
        // Handle configuration options
    }

    public function getVisitor(AnalysisContext $context): \PhpParser\NodeVisitor
    {
        return new class($context) extends NodeVisitorAbstract {
            public function __construct(private AnalysisContext $context) {}

            public function enterNode(Node $node): ?int
            {
                // Detect deprecated method calls
                if ($node instanceof Node\Expr\MethodCall) {
                    $methodName = $node->name->toString();

                    if ($methodName === 'deprecatedMethod') {
                        $this->context->addIssue(new Issue(
                            type: 'deprecated_method',
                            message: 'deprecatedMethod() is deprecated in SS6',
                            line: $node->getLine(),
                            suggestion: 'Use newMethod() instead',
                            docsUrl: 'https://docs.silverstripe.org/...'
                        ));
                    }
                }
                return null;
            }
        };
    }
}

// Return the class name for auto-loading
return DeprecatedMethodPlugin::class;

在您的配置中注册:

{
  "customPlugins": [
    "./plugins/DeprecatedMethodPlugin.php"
  ],
  "plugins": {
    "deprecated-method-validator": {
      "enabled": true
    }
  }
}

测试

该项目包括针对PHP和TypeScript的全面测试套件:

# Run PHP tests (PHPUnit)
cd php && composer test

# Run TypeScript tests (Vitest)
npm test

# Run all tests
npm run test:all

# Watch mode for development
npm run test:watch

项目结构

silverstripe-mcp/
├── src/                          # TypeScript MCP server
│   ├── index.ts                  # Entry point, stdio transport
│   ├── tools/
│   │   └── ss-validator.ts       # Main validation tool
│   └── lib/
│       └── php-bridge.ts         # PHP subprocess communication
│
├── php/                          # PHP analyzer
│   ├── bin/
│   │   └── analyze               # CLI entry point
│   ├── src/
│   │   ├── AnalyzerRunner.php    # Plugin orchestration
│   │   ├── AnalysisContext.php   # Shared analysis state
│   │   ├── Issue.php             # Issue data structure
│   │   ├── Contracts/
│   │   │   └── ValidatorPluginInterface.php
│   │   ├── Plugins/              # Validator plugins
│   │   │   ├── NamespaceValidatorPlugin.php      (core)
│   │   │   ├── BuildTaskValidatorPlugin.php      (core)
│   │   │   ├── FormFieldValuePlugin.php          (core)
│   │   │   ├── RemovedMethodPlugin.php           (core)
│   │   │   ├── HookRenamePlugin.php              (core)
│   │   │   ├── DeprecatedConfigPlugin.php        (core)
│   │   │   ├── ExtensionHookVisibilityPlugin.php (auto: Extension classes)
│   │   │   └── ElementalNamespacePlugin.php      (auto: Elemental imports)
│   │   └── Config/
│   │       ├── namespace-mappings.php
│   │       ├── removed-methods.php
│   │       ├── hook-renames.php
│   │       └── elemental-mappings.php
│   └── tests/                    # PHPUnit tests
│
├── tests/                        # Vitest tests
│   ├── php-bridge.test.ts
│   ├── ss-validator.test.ts
│   └── fixtures/
│
├── docs/
│   ├── architecture.md                    # Technical architecture
│   └── recommended-agent-instructions.md  # Setup for AI agents
├── silverstripe-mcp.example.json # Example configuration
├── CLAUDE.md                     # Development instructions
└── README.md

发展

# Build and watch for changes
npm run dev

# Test PHP analyzer directly
cd php && php bin/analyze '{"code": "<?php use SilverStripe\\ORM\\ArrayList;"}'

# Example output:
{
  "issues": [{
    "type": "deprecated_import",
    "message": "'SilverStripe\\ORM\\ArrayList' has moved to 'SilverStripe\\Model\\List\\ArrayList' in Silverstripe 6",
    "line": 1,
    "suggestion": "use SilverStripe\\Model\\List\\ArrayList;",
    "docsUrl": "https://docs.silverstripe.org/en/6/changelogs/6.0.0/#renamed-classes"
  }],
  "suggestions": [],
  "rerun": true
}

看 贡献.md 详细的开发说明。

需求

  • Node.js 18.0或更高
  • PHP 8.3或更高
  • 作曲家 用于PHP依赖管理

贡献

欢迎投稿!看 贡献.md 了解开发设置、架构细节和测试指南。

学分

许可证

MIT许可证-请参阅 许可证 了解详情。